From 2a33ba63ae2f3d85cd83d489398b6002d2459287 Mon Sep 17 00:00:00 2001 From: htt1997 Date: Tue, 1 Aug 2023 10:52:26 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- data_object/CODEOWNERS | 17 + .../adaptor/distributed_objectstore_impl.h | 2 +- .../include/communicator/app_pipe_handler.h | 4 +- .../include/communicator/app_pipe_mgr.h | 4 +- .../include/communicator/app_types.h | 21 + .../communicator/communication_provider.h | 4 +- .../communication_provider_impl.h | 2 +- .../communicator/process_communicator_impl.h | 2 + .../include/communicator/softbus_adapter.h | 52 +- .../src/adaptor/client_adaptor.cpp | 17 +- .../src/adaptor/distributed_object_impl.cpp | 18 +- .../adaptor/distributed_object_store_impl.cpp | 6 +- .../src/communicator/app_pipe_handler.cpp | 6 +- .../src/communicator/app_pipe_mgr.cpp | 14 +- .../communication_provider_impl.cpp | 6 +- .../process_communicator_impl.cpp | 10 +- .../communicator/softbus_adapter_standard.cpp | 278 ++++-- .../src/object_service_proxy.cpp | 41 +- .../distributedtest/data_object_test/BUILD.gn | 4 +- .../test/fuzztest/objectstore_fuzzer/BUILD.gn | 2 +- .../innerkitsimpl/test/unittest/BUILD.gn | 2 +- .../include/mock_app_data_change_listener.h | 8 +- .../include/mock_app_device_change_listener.h | 63 +- .../mock/include/mock_flat_object_watcher.h | 34 + .../mock/include/mock_object_watcher.h | 37 + .../test/unittest/mock/src/mock_soft_bus.cpp | 6 +- .../test/unittest/src/app_pipe_mgr_test.cpp | 134 ++- .../test/unittest/src/communicator_test.cpp | 358 ++++--- .../test/unittest/src/object_store_test.cpp | 555 ++++++++++- .../src/process_communicator_impl_test.cpp | 65 +- .../include/adaptor/js_object_wrapper.h | 2 +- .../jskitsimpl/include/common/uv_queue.h | 7 +- .../src/adaptor/js_object_wrapper.cpp | 2 +- .../jskitsimpl/src/adaptor/js_watcher.cpp | 4 +- .../jskitsimpl/src/common/uv_queue.cpp | 27 +- .../jskitsimpl/test/unittest/src/config.json | 1 + data_object/interfaces/innerkits/BUILD.gn | 2 +- data_object/interfaces/jskits/BUILD.gn | 4 +- .../entry/src/main/config.json | 1 + data_share/bundle.json | 4 +- .../native/common/include/callbacks_manager.h | 48 +- .../common/include/datashare_itypes_utils.h | 23 +- ...ibuteddata_data_share_ipc_interface_code.h | 4 +- .../native/common/include/idatashare.h | 5 + .../common/include/ikvstore_data_service.h | 3 + .../common/src/datashare_itypes_utils.cpp | 54 + .../common/src/ikvstore_data_service.cpp | 28 + .../common/src/ishared_result_set_stub.cpp | 2 +- .../provider/include/ext_special_controller.h | 5 + .../provider/src/ext_special_controller.cpp | 30 + .../consumer/include/datashare_helper_impl.h | 4 + .../native/consumer/include/datashare_proxy.h | 4 + .../consumer/src/datashare_connection.cpp | 14 +- .../native/consumer/src/datashare_helper.cpp | 25 +- .../consumer/src/datashare_helper_impl.cpp | 22 + .../native/consumer/src/datashare_proxy.cpp | 54 + .../provider/include/datashare_ext_ability.h | 22 + .../native/provider/include/datashare_stub.h | 5 + .../provider/src/datashare_ext_ability.cpp | 10 + .../native/provider/src/datashare_stub.cpp | 54 + .../native/proxy/include/ams_mgr_proxy.h | 57 ++ .../proxy/include/data_share_manager_impl.h | 4 + .../idata_share_client_death_observer.h | 49 + .../published_data_subscriber_manager.h | 2 +- .../proxy/include/rdb_subscriber_manager.h | 2 +- .../native/proxy/src/ams_mgr_proxy.cpp | 108 ++ .../proxy/src/data_share_manager_impl.cpp | 17 + .../src/idata_share_client_death_observer.cpp | 31 + .../src/published_data_subscriber_manager.cpp | 13 +- .../proxy/src/rdb_subscriber_manager.cpp | 11 +- data_share/interfaces/inner_api/BUILD.gn | 6 +- .../include/datashare_operation_statement.h | 55 ++ .../common/include/datashare_template.h | 3 +- .../consumer/include/datashare_helper.h | 37 +- data_share/test/native/BUILD.gn | 6 +- .../proxydatas_with_permission_test.cpp | 86 +- .../src/errorcode_test.cpp | 2 + .../mediadatashare_test/src/join_test.cpp | 1 + .../src/mediadatashare_unit_test.cpp | 276 +++++- .../src/slientaccess_test.cpp | 1 + datamgr_service/bundle.json | 6 +- datamgr_service/datamgr_service.gni | 2 + datamgr_service/hisysevent.yaml | 9 + .../adapter/CMakeLists.txt | 1 + .../src/account_delegate_default_impl.cpp | 2 +- .../adapter/communicator/BUILD.gn | 3 + .../communicator/src/app_pipe_handler.cpp | 6 +- .../communicator/src/app_pipe_handler.h | 4 +- .../adapter/communicator/src/app_pipe_mgr.cpp | 12 +- .../adapter/communicator/src/app_pipe_mgr.h | 4 +- .../src/communication_provider_impl.cpp | 6 +- .../src/communication_provider_impl.h | 4 +- .../communicator/src/communicator_context.cpp | 34 + .../adapter/communicator/src/data_buffer.cpp | 8 - .../adapter/communicator/src/data_buffer.h | 10 +- .../src/device_manager_adapter.cpp | 116 ++- .../src/process_communicator_impl.cpp | 10 +- .../communicator/src/softbus_adapter.h | 4 +- .../src/softbus_adapter_standard.cpp | 19 +- .../communicator/src/softbus_client.cpp | 158 ++- .../adapter/communicator/src/softbus_client.h | 23 +- .../communication_provider_impl_test.cpp | 3 +- .../src/behaviour/behaviour_reporter_impl.cpp | 8 +- .../src/behaviour/behaviour_reporter_impl.h | 1 + .../adapter/dfx/src/dfx_code_constant.h | 1 + .../adapter/dfx/src/hiview_adapter.cpp | 27 + .../adapter/dfx/src/hiview_adapter.h | 1 + .../include/communicator/commu_types.h | 15 + .../communicator/communication_provider.h | 4 +- .../communicator/communicator_context.h | 40 + .../communicator/device_manager_adapter.h | 7 + .../communicator/process_communicator_impl.h | 2 + .../adapter/include/dfx/behaviour_reporter.h | 1 + .../adapter/include/dfx/dfx_types.h | 9 + .../adapter/include/dfx/reporter.h | 2 +- .../permission/src/permission_validator.cpp | 15 +- .../distributeddataservice/app/BUILD.gn | 2 +- .../app/distributed_data.cfg | 6 +- .../app/src/kvstore_data_service.cpp | 13 + .../app/src/kvstore_data_service.h | 2 + .../app/src/kvstore_device_listener.cpp | 2 + .../app/src/kvstore_meta_manager.cpp | 6 +- .../app/src/security/security.cpp | 9 +- .../app/src/uninstaller/BUILD.gn | 2 +- .../framework/CMakeLists.txt | 2 +- .../framework/include/error/general_error.h | 7 +- .../framework/include/store/cursor.h | 2 + .../framework/include/store/general_store.h | 7 + .../framework/store/auto_cache.cpp | 8 +- .../framework/test/serializable_test.cpp | 1 + .../distributeddataservice/service/BUILD.gn | 13 +- .../service/CMakeLists.txt | 1 + .../service/cloud/cloud_service_impl.cpp | 101 +- .../service/cloud/cloud_service_impl.h | 31 +- .../service/cloud/sync_manager.cpp | 13 +- .../service/data_share/BUILD.gn | 5 +- .../data_share/common/base64_utils.cpp | 181 ++++ .../common/base64_utils.h} | 32 +- .../service/data_share/common/callback_impl.h | 1 - .../common/extension_connect_adaptor.cpp | 7 +- .../data_share/common/extension_mgr_proxy.cpp | 110 +++ .../data_share/common/extension_mgr_proxy.h | 58 ++ .../data_share/common/scheduler_manager.cpp | 46 +- .../data_share/common/scheduler_manager.h | 1 + .../data_share/data/published_data.cpp | 45 + .../service/data_share/data/published_data.h | 13 +- .../data/resultset_json_formatter.cpp | 1 + .../data_share/data_share_service_impl.cpp | 69 +- .../data_share/data_share_service_impl.h | 14 +- .../service/data_share/gaussdb_rd/BUILD.gn | 1 + .../src/common/include/collection_option.h | 3 - .../gaussdb_rd/src/common/include/doc_limit.h | 2 +- .../src/common/include/document_type.h | 2 +- .../src/common/src/collection_option.cpp | 20 - .../gaussdb_rd/src/common/src/db_config.cpp | 4 + .../gaussdb_rd/src/common/src/json_common.cpp | 59 +- .../src/executor/document/check_common.cpp | 22 +- .../src/executor/document/check_common.h | 8 +- .../src/interface/include/collection.h | 18 +- .../src/interface/include/doc_errno.h | 1 + .../src/interface/include/document_key.h | 48 + .../src/interface/include/document_store.h | 9 +- .../src/interface/include/result_set.h | 12 +- .../src/interface/include/result_set_common.h | 2 +- .../src/interface/src/collection.cpp | 147 +-- .../src/interface/src/doc_errno.cpp | 6 +- .../src/interface/src/document_key.cpp | 51 + .../src/interface/src/document_store.cpp | 286 ++++-- .../src/interface/src/result_set.cpp | 184 ++-- .../src/interface/src/result_set_common.cpp | 14 +- .../src/oh_adapter/include/json_object.h | 7 +- .../oh_adapter/include/kv_store_executor.h | 14 +- .../src/oh_adapter/src/json_object.cpp | 114 +-- .../src/oh_adapter/src/kv_store_manager.cpp | 1 - .../src/sqlite_store_executor_impl.cpp | 119 ++- .../src/sqlite_store_executor_impl.h | 14 +- .../src/oh_adapter/src/sqlite_utils.cpp | 39 +- .../src/oh_adapter/src/sqlite_utils.h | 3 +- .../gaussdb_rd/test/unittest/BUILD.gn | 1 + .../test/unittest/api/documentdb_api_test.cpp | 82 +- .../unittest/api/documentdb_data_test.cpp | 59 +- .../unittest/api/documentdb_insert_test.cpp | 8 +- .../documentdb_json_common_test.cpp | 15 - ...d_config_from_data_proxy_node_strategy.cpp | 3 +- .../general/load_config_common_strategy.cpp | 4 +- .../strategies/get_data_strategy.cpp | 5 +- .../strategies/publish_strategy.cpp | 5 +- .../strategies/rdb_notify_strategy.cpp | 2 +- .../published_data_subscriber_manager.cpp | 133 +-- .../published_data_subscriber_manager.h | 44 +- .../rdb_subscriber_manager.cpp | 170 ++-- .../rdb_subscriber_manager.h | 45 +- .../service/kvdb/user_delegate.cpp | 7 +- .../service/matrix/src/matrix_event.cpp | 1 - .../service/rdb/rdb_asset_loader.cpp | 26 +- .../service/rdb/rdb_cloud.cpp | 21 +- .../service/rdb/rdb_cloud.h | 2 +- .../service/rdb/rdb_cursor.cpp | 86 +- .../service/rdb/rdb_cursor.h | 8 +- .../service/rdb/rdb_general_store.cpp | 206 +++- .../service/rdb/rdb_general_store.h | 17 +- .../service/rdb/rdb_query.cpp | 106 +- .../service/rdb/rdb_query.h | 32 + .../service/rdb/rdb_result_set_impl.cpp | 209 ++-- .../service/rdb/rdb_result_set_impl.h | 46 +- .../service/rdb/rdb_service_impl.cpp | 493 +++++----- .../service/rdb/rdb_service_impl.h | 36 +- .../service/rdb/rdb_syncer.cpp | 439 --------- .../service/rdb/rdb_syncer.h | 119 --- .../service/rdb/value_proxy.cpp | 19 + .../service/rdb/value_proxy.h | 17 + .../service/test/BUILD.gn | 38 + .../fuzztest/cloudservicestub_fuzzer/BUILD.gn | 3 +- .../cloudservicestub_fuzzer.cpp | 49 +- .../datashareservicestub_fuzzer/BUILD.gn | 5 +- .../datashareservicestub_fuzzer.cpp | 16 +- .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 3 + .../kvdbservicestub_fuzzer.cpp | 22 +- .../objectservicestub_fuzzer/BUILD.gn | 10 +- .../objectservicestub_fuzzer.cpp | 14 +- .../fuzztest/rdbresultsetstub_fuzzer/BUILD.gn | 36 - .../rdbresultsetstub_fuzzer.cpp | 7 +- .../fuzztest/rdbservicestub_fuzzer/BUILD.gn | 2 - .../rdbservicestub_fuzzer.cpp | 14 +- .../udmfservice_fuzzer/udmfservice_fuzzer.cpp | 4 +- .../service/test/mock/cursor_mock.cpp | 132 +++ .../service/test/mock/cursor_mock.h | 49 + .../service/test/rdb_result_set_impl_test.cpp | 213 ++++ .../service/udmf/BUILD.gn | 19 +- .../service/udmf/data_manager.cpp | 96 +- .../service/udmf/data_manager.h | 2 +- .../service/udmf/lifecycle/lifecycle_policy.h | 2 - .../udmf/preprocess/preprocess_utils.cpp | 108 +- .../udmf/preprocess/preprocess_utils.h | 7 + .../service/udmf/store/runtime_store.cpp | 31 +- .../service/udmf/udmf_service_impl.cpp | 43 +- kv_store/CODEOWNERS | 19 + kv_store/bundle.json | 70 ++ kv_store/frameworks/common/executor_pool.h | 86 +- kv_store/frameworks/common/log_print.h | 2 +- .../common/test/executor_pool_test.cpp | 36 +- .../innerkitsimpl/kvdb/src/store_factory.cpp | 3 - .../kvdb/test/auto_sync_timer_test.cpp | 4 +- .../src/js_single_kv_store.cpp | 2 + .../distributedkvstore/src/js_util.cpp | 2 +- .../distributeddb/common/include/db_errno.h | 2 + .../distributeddb/common/include/db_types.h | 1 + .../common/include/relational/table_info.h | 3 + .../distributeddb/common/src/auto_launch.cpp | 3 + .../common/src/relational/table_info.cpp | 17 +- .../common/src/runtime_context_impl.cpp | 2 + .../common/src/time_tick_monitor.cpp | 1 + .../include/communicator_aggregator.h | 2 +- .../communicator/include/iadapter.h | 5 +- .../communicator/include/network_adapter.h | 5 +- .../include/send_task_scheduler.h | 5 +- .../src/communicator_aggregator.cpp | 9 +- .../communicator/src/network_adapter.cpp | 4 +- .../communicator/src/send_task_scheduler.cpp | 16 +- .../libs/distributeddb/distributeddb.gni | 1 + .../include/iprocess_communicator.h | 6 + .../relational/relational_store_delegate.h | 2 + .../interfaces/include/store_types.h | 1 + .../interfaces/src/kv_store_errno.cpp | 1 + .../relational_store_delegate_impl.cpp | 29 +- .../relational_store_delegate_impl.h | 2 + .../relational/relational_store_manager.cpp | 8 +- .../relational/relational_sync_able_storage.h | 10 +- .../include/cloud/cloud_storage_utils.h | 16 +- .../storage/include/cloud/schema_mgr.h | 3 +- .../include/icloud_sync_storage_interface.h | 4 +- .../distributeddb/storage/include/ikvdb.h | 4 - .../storage/include/ikvdb_factory.h | 2 +- .../include/relational_store_connection.h | 1 + .../storage/include/storage_proxy.h | 5 +- .../storage/include/sync_generic_interface.h | 5 + .../storage/src/cloud/cloud_storage_utils.cpp | 167 +++- .../storage/src/cloud/schema_mgr.cpp | 40 +- .../storage/src/data_transformer.cpp | 4 +- .../storage/src/data_transformer.h | 2 +- .../storage/src/default_factory.cpp | 6 +- .../storage/src/default_factory.h | 2 +- .../storage/src/generic_kvdb.cpp | 16 +- .../distributeddb/storage/src/generic_kvdb.h | 6 +- .../storage/src/kvdb_manager.cpp | 6 + .../src/operation/local_database_oper.cpp | 2 + .../src/operation/local_database_oper.h | 2 + .../src/relational_sync_able_storage.cpp | 54 +- .../relational/sqlite_relational_store.cpp | 46 +- .../relational/sqlite_relational_store.h | 8 +- .../sqlite_relational_store_connection.cpp | 18 +- .../sqlite_relational_store_connection.h | 2 +- ...qlite_single_relational_storage_engine.cpp | 7 +- .../sqlite_single_relational_storage_engine.h | 2 +- .../storage/src/sqlite/sqlite_local_kvdb.cpp | 2 + .../storage/src/sqlite/sqlite_local_kvdb.h | 3 +- .../sqlite/sqlite_local_kvdb_connection.cpp | 2 + .../src/sqlite/sqlite_local_kvdb_connection.h | 3 +- .../src/sqlite/sqlite_local_kvdb_snapshot.cpp | 2 + .../src/sqlite/sqlite_local_kvdb_snapshot.h | 3 +- .../sqlite_single_ver_natural_store.cpp | 78 +- .../sqlite/sqlite_single_ver_natural_store.h | 23 +- ...te_single_ver_natural_store_connection.cpp | 4 + ...single_ver_relational_storage_executor.cpp | 152 +-- ...e_single_ver_relational_storage_executor.h | 18 +- ...ver_relational_storage_extend_executor.cpp | 15 +- .../sqlite_single_ver_storage_engine.cpp | 1 + .../storage/src/sqlite/sqlite_utils.cpp | 2 +- .../storage/src/storage_engine.cpp | 16 + .../storage/src/storage_engine.h | 5 + .../storage/src/storage_proxy.cpp | 16 +- .../storage/src/sync_able_kvdb.cpp | 17 +- .../storage/src/sync_able_kvdb.h | 2 +- .../syncer/src/cloud/cloud_db_proxy.cpp | 39 +- .../syncer/src/cloud/cloud_db_proxy.h | 3 + .../src/cloud/cloud_force_pull_strategy.cpp | 14 +- .../src/cloud/cloud_force_pull_strategy.h | 3 +- .../src/cloud/cloud_force_push_strategy.cpp | 40 +- .../src/cloud/cloud_force_push_strategy.h | 3 +- .../syncer/src/cloud/cloud_merge_strategy.cpp | 16 +- .../syncer/src/cloud/cloud_merge_strategy.h | 3 +- .../syncer/src/cloud/cloud_sync_strategy.h | 4 +- .../syncer/src/cloud/cloud_sync_utils.cpp | 119 +++ .../syncer/src/cloud/cloud_sync_utils.h | 38 + .../syncer/src/cloud/cloud_syncer.cpp | 385 ++++---- .../syncer/src/cloud/cloud_syncer.h | 49 +- .../syncer/src/device_manager.cpp | 2 + .../distributeddb/syncer/src/device_manager.h | 4 + .../syncer/src/generic_syncer.cpp | 5 + .../distributeddb/syncer/src/isync_engine.h | 2 + .../syncer/src/remote_executor.cpp | 12 +- .../syncer/src/remote_executor.h | 1 + .../syncer/src/single_ver_data_sync.cpp | 17 +- .../src/single_ver_relational_syncer.cpp | 9 +- .../distributeddb/syncer/src/sync_engine.cpp | 2 + .../distributeddb/syncer/src/sync_engine.h | 2 + .../syncer/src/sync_operation.cpp | 14 +- .../distributeddb/syncer/src/time_sync.cpp | 17 +- .../libs/distributeddb/syncer/src/time_sync.h | 4 +- .../libs/distributeddb/test/BUILD.gn | 2 + .../test/fuzztest/cloudsync_fuzzer/BUILD.gn | 116 +++ .../cloudsync_fuzzer/cloudsync_fuzzer.cpp | 228 +++++ .../cloudsync_fuzzer/cloudsync_fuzzer.h | 21 + .../fuzztest/cloudsync_fuzzer/corpus/init | 14 + .../fuzztest/cloudsync_fuzzer/project.xml | 25 + .../common/distributeddb_tools_unit_test.cpp | 25 + .../common/distributeddb_tools_unit_test.h | 2 + .../common/communicator/adapter_stub.cpp | 5 +- .../common/communicator/adapter_stub.h | 2 +- .../distributeddb_communicator_deep_test.cpp | 21 +- ...eddb_interfaces_import_and_export_test.cpp | 55 ++ ...tributeddb_interfaces_nb_delegate_test.cpp | 68 +- ...stributeddb_interfaces_relational_test.cpp | 233 ++++- ..._cloud_interfaces_relational_sync_test.cpp | 931 ++++++++++++++---- ...stributeddb_cloud_save_cloud_data_test.cpp | 85 +- .../distributeddb_cloud_schema_mgr_test.cpp | 173 ++++ .../distributeddb_data_transformer_test.cpp | 2 +- ...relational_cloud_syncable_storage_test.cpp | 160 +++ ...distributeddb_relational_get_data_test.cpp | 2 +- ...ributeddb_storage_data_connection_test.cpp | 4 +- ...tributeddb_storage_data_operation_test.cpp | 6 +- ...e_sqlite_single_ver_natural_store_test.cpp | 37 +- .../mock_sqlite_single_ver_natural_store.h | 35 + .../common/syncer/cloud/cloud_syncer_test.h | 4 +- ...distributeddb_cloud_asset_compare_test.cpp | 1 - .../distributeddb_cloud_db_proxy_test.cpp | 129 +++ .../distributeddb_cloud_strategy_test.cpp | 59 +- ...ddb_cloud_syncer_progress_manager_test.cpp | 3 +- ...distributeddb_cloud_syncer_upload_test.cpp | 195 ---- .../common/syncer/cloud/mock_asset_loader.h | 29 + .../mock_icloud_sync_storage_interface.h | 5 +- .../syncer/cloud/virtual_asset_loader.cpp | 12 + .../syncer/cloud/virtual_asset_loader.h | 6 + .../common/syncer/cloud/virtual_cloud_db.cpp | 59 +- .../common/syncer/cloud/virtual_cloud_db.h | 5 + .../syncer/cloud/virtual_cloud_syncer.cpp | 14 + .../syncer/cloud/virtual_cloud_syncer.h | 2 + .../distributeddb_mock_sync_module_test.cpp | 42 +- ...stributeddb_relational_multi_user_test.cpp | 35 + ...ributeddb_relational_ver_p2p_sync_test.cpp | 113 ++- ...teddb_single_ver_p2p_complex_sync_test.cpp | 28 +- ...stributeddb_syncer_device_manager_test.cpp | 6 +- .../syncer/mock_single_ver_state_machine.h | 5 + .../unittest/common/syncer/mock_time_sync.h | 12 + .../virtual_communicator_aggregator.cpp | 16 + .../syncer/virtual_communicator_aggregator.h | 4 + ...rtual_relational_ver_sync_db_interface.cpp | 3 +- .../unittest/distributedKVStore/config.json | 3 +- .../test/unittest/distributeddata/config.json | 3 +- mock/include/CMakeLists.txt | 14 +- .../include/data_ability_observer_interface.h | 12 +- .../include/data_ability_observer_stub.h | 6 + .../include/extension_manager_client.h | 81 ++ .../include/extension_manager_interface.h | 65 ++ .../include/extension_manager_proxy.h | 67 ++ .../include/common_event_subscribe_info.h | 1 + .../include/transport/session.h | 657 +++++++----- .../api/js/napi/backup_ext/BUILD.gn | 52 + .../backup_ext/backup_extension_ability.js | 26 + .../interfaces/common/file_share_sandbox.json | 52 + .../interfaces/common/include/common_func.h | 33 + .../interfaces/common/include/json_utils.h | 35 + .../interfaces/common/include/log.h | 38 + .../common/include/sandbox_helper.h | 36 + .../interfaces/common/src/common_func.cpp | 111 +++ .../interfaces/common/src/json_utils.cpp | 66 ++ .../interfaces/common/src/sandbox_helper.cpp | 176 ++++ .../native/backup_kit_inner/BUILD.gn | 66 ++ .../backup_kit_inner/backup_kit_inner.h | 23 + .../backup_kit_inner/impl/b_file_info.h | 44 + .../backup_kit_inner/impl/b_session_backup.h | 85 ++ .../backup_kit_inner/impl/b_session_restore.h | 103 ++ .../impl/b_session_restore_async.h | 131 +++ .../backup_kit_inner/impl/i_extension.h | 37 + .../impl/i_extension_ipc_interface_code.h | 29 + .../native/backup_kit_inner/impl/i_service.h | 58 ++ .../impl/i_service_ipc_interface_code.h | 36 + .../backup_kit_inner/impl/i_service_reverse.h | 48 + .../i_service_reverse_ipc_interface_code.h | 34 + .../backup_kit_inner/impl/service_proxy.h | 72 ++ .../impl/svc_death_recipient.h | 40 + .../interfaces/innerkits/native/BUILD.gn | 131 +++ .../native/file_share/include/file_share.h | 42 + .../native/file_share/src/file_share.cpp | 292 ++++++ .../native/file_uri/include/file_uri.h | 39 + .../native/file_uri/src/file_uri.cpp | 76 ++ .../include/remote_file_share.h | 45 + .../src/remote_file_share.cpp | 350 +++++++ .../interfaces/kits/js/BUILD.gn | 139 +++ .../kits/js/backup/general_callbacks.h | 42 + .../kits/js/backup/local_capabilities.cpp | 65 ++ .../kits/js/backup/local_capabilities.h | 29 + .../interfaces/kits/js/backup/module.cpp | 47 + .../kits/js/backup/prop_n_exporter.cpp | 38 + .../kits/js/backup/prop_n_exporter.h | 34 + .../js/backup/session_backup_n_exporter.cpp | 279 ++++++ .../js/backup/session_backup_n_exporter.h | 35 + .../js/backup/session_restore_n_exporter.cpp | 421 ++++++++ .../js/backup/session_restore_n_exporter.h | 40 + .../js/file_share/fileshare_n_exporter.cpp | 36 + .../kits/js/file_share/fileshare_n_exporter.h | 27 + .../js/file_share/grant_uri_permission.cpp | 252 +++++ .../kits/js/file_share/grant_uri_permission.h | 60 ++ .../kits/js/file_uri/file_uri_n_exporter.cpp | 49 + .../kits/js/file_uri/file_uri_n_exporter.h | 27 + .../kits/js/file_uri/get_uri_from_path.cpp | 54 + .../kits/js/file_uri/get_uri_from_path.h | 33 +- .../remotefileshare_n_exporter.cpp | 137 +++ .../remotefileshare_n_exporter.h | 28 + .../remotefileshare_napi.cpp | 37 + .../remote_file_share/remotefileshare_napi.h | 27 + .../tools/backup_tool/BUILD.gn | 52 + .../tools/backup_tool/include/tools_op.h | 121 +++ .../tools/backup_tool/src/main.cpp | 99 ++ .../tools/backup_tool/src/tools_op.cpp | 87 ++ .../tools/backup_tool/src/tools_op_backup.cpp | 294 ++++++ .../backup_tool/src/tools_op_check_sa.cpp | 53 + .../tools/backup_tool/src/tools_op_help.cpp | 62 ++ .../backup_tool/src/tools_op_restore.cpp | 330 +++++++ .../src/tools_op_restore_async.cpp | 310 ++++++ .../app_file_service/utils/BUILD.gn | 105 ++ .../utils/include/b_encryption/b_encryption.h | 23 + .../utils/include/b_error/b_error.h | 258 +++++ .../utils/include/b_error/b_excep_utils.h | 77 ++ .../utils/include/b_filesystem/b_dir.h | 62 ++ .../utils/include/b_filesystem/b_file.h | 68 ++ .../utils/include/b_hilog/filemgmt_libhilog.h | 52 + .../include/b_json/b_json_cached_entity.h | 161 +++ .../utils/include/b_json/b_json_entity.h | 57 ++ .../utils/include/b_json/b_json_entity_caps.h | 123 +++ .../include/b_json/b_json_entity_ext_manage.h | 80 ++ .../b_json/b_json_entity_extension_config.h | 65 ++ .../include/b_ohos/startup/backup_para.h | 31 + .../utils/include/b_process/b_guard_cwd.h | 51 + .../utils/include/b_process/b_guard_signal.h | 52 + .../utils/include/b_process/b_multiuser.h | 40 + .../utils/include/b_process/b_process.h | 54 + .../utils/include/b_resources/b_constants.h | 174 ++++ .../include/b_tarball/b_tarball_cmdline.h | 40 + .../include/b_tarball/b_tarball_factory.h | 77 ++ .../app_file_service/utils/rust/src/lib.rs | 38 + .../utils/src/b_encryption/b_encryption.cpp | 27 + .../utils/src/b_error/b_error.cpp | 63 ++ .../utils/src/b_error/b_excep_utils.cpp | 41 + .../utils/src/b_filesystem/b_dir.cpp | 187 ++++ .../utils/src/b_filesystem/b_file.cpp | 143 +++ .../utils/src/b_ipc/b_want_2_ext.cpp | 30 + .../src/b_json/b_json_entity_ext_manage.cpp | 223 +++++ .../b_json/b_json_entity_extension_config.cpp | 129 +++ .../utils/src/b_ohos/startup/backup_para.cpp | 68 ++ .../utils/src/b_process/b_guard_cwd.cpp | 42 + .../utils/src/b_process/b_guard_signal.cpp | 41 + .../utils/src/b_process/b_process.cpp | 116 +++ .../utils/src/b_tarball/b_tarball_cmdline.cpp | 99 ++ .../utils/src/b_tarball/b_tarball_factory.cpp | 181 ++++ .../file_api/interfaces/kits/security_label.h | 82 ++ mock/innerkits/netmanager_base/BUILD.gn | 35 - .../innerkits/include/inet_addr.h | 49 + .../innerkits/include/net_manager_constants.h | 139 +++ .../innerkits/netconnclient/BUILD.gn | 143 +++ .../netconnclient/connect_blocklist.txt | 18 + .../netconnclient/include/http_proxy.h | 60 ++ .../include/net_all_capabilities.h | 67 ++ .../netconnclient/include/net_conn_client.h | 384 ++++++++ .../include/net_conn_constants.h | 56 ++ .../netconnclient/include/net_handle.h} | 58 +- .../include/net_interface_config.h | 41 + .../netconnclient}/include/net_link_info.h | 15 +- .../netconnclient}/include/net_specifier.h | 4 +- .../include/net_supplier_callback_base.h} | 31 +- .../include/net_supplier_info.h | 4 +- .../include/proxy/conn_ipc_interface_code.h | 106 ++ .../include/proxy/i_net_adj_callback.h | 34 + .../include/proxy/i_net_adj_service.h | 41 + .../include/proxy/i_net_conn_callback.h | 44 + .../include/proxy/i_net_conn_service.h | 82 ++ .../include/proxy/i_net_detection_callback.h | 38 + .../include/proxy/i_net_interface_callback.h | 43 + .../include/proxy/i_net_supplier_callback.h | 41 + .../include/proxy/net_conn_callback_stub.h | 57 ++ .../include/proxy/net_conn_service_proxy.h} | 111 +-- .../proxy/net_detection_callback_stub.h | 46 + .../proxy/net_interface_callback_stub.h | 59 ++ .../proxy/net_supplier_callback_stub.h | 56 ++ .../netconnclient}/include/route.h | 9 +- .../netconnclient/include/socket_permission.h | 22 + .../netconnclient/libnetconn_kits.map | 145 +++ .../innerkits/netmanagernative/BUILD.gn | 97 ++ .../include/dhcp_result_parcel.h | 40 + .../netmanagernative/include/fwmark.h | 46 + .../netmanagernative/include/fwmark_command.h | 30 + .../include/i_netsys_service.h | 119 +++ .../include/i_notify_callback.h | 49 + .../netmanagernative/include/interface_type.h | 49 + .../netmanagernative/include/iptables_type.h | 54 + .../include/netnative_log_wrapper.h | 41 + .../include/netsys_addr_info_parcel.h | 53 + .../include/netsys_ipc_interface_code.h | 105 ++ .../include/netsys_native_service_proxy.h | 113 +++ .../include/network_permission.h | 28 + .../include/network_sharing.h | 29 + .../include/notify_callback_proxy.h | 45 + .../include/notify_callback_stub.h | 52 + .../netmanagernative/include/route_type.h | 38 + .../netmanagernative/include/uid_range.h | 55 ++ .../innerkits/netpolicyclient/BUILD.gn | 102 ++ .../include/net_policy_client.h | 334 +++++++ .../include/net_policy_constants.h | 102 ++ .../include/net_quota_policy.h | 116 +++ .../include/proxy/i_net_policy_callback.h | 88 ++ .../include/proxy/i_net_policy_service.h | 221 +++++ .../include/proxy/net_policy_callback_stub.h | 58 ++ .../include/proxy/net_policy_service_proxy.h | 63 ++ .../include/proxy/policy_ipc_interface_code.h | 57 ++ .../netpolicyclient/libnetpolicy_kits.map | 73 ++ .../innerkits/netstatsclient/BUILD.gn | 104 ++ .../include/data_flow_statistics.h | 106 ++ .../netstatsclient/include/net_stats_client.h | 233 +++++ .../include/net_stats_constants.h | 44 + .../netstatsclient/include/net_stats_info.h | 88 ++ .../include/proxy/i_net_stats_callback.h | 35 + .../include/proxy/i_net_stats_service.h | 56 ++ .../include/proxy/net_stats_callback_stub.h | 46 + .../include/proxy/net_stats_service_proxy.h | 58 ++ .../include/proxy/stats_ipc_interface_code.h | 50 + .../netstatsclient/libnetstats_kits.map | 97 ++ .../include/net_policy_client.h | 192 ---- mock/innerkits/netmanager_base/sdk_info.json | 17 - .../appkit/ability_runtime/context/context.h | 306 +++--- .../ability_runtime/context/context_impl.h | 403 +++++--- mock/src/mock_aa_fwk.cpp | 21 + mock/src/mock_access_token.cpp | 21 +- mock/src/mock_context.cpp | 71 +- mock/src/mock_filemanagement.cpp | 17 + mock/src/mock_netmanager.cpp | 212 ++++ mock/src/mock_notification.cpp | 40 + preferences/CMakeLists.txt | 2 + preferences/bundle.json | 11 +- .../js/napi/common/include/js_ability.h | 18 +- .../js/napi/common/include/napi_async_call.h | 12 +- .../common/include/napi_preferences_error.h | 93 +- .../mock/cross_platform/include/js_ability.h | 17 +- .../mock/cross_platform/src/js_ability.cpp | 27 +- .../js/napi/common/mock/include/js_ability.h | 17 +- .../js/napi/common/mock/src/js_ability.cpp | 35 +- .../js/napi/common/src/js_ability.cpp | 72 +- .../js/napi/common/src/napi_async_call.cpp | 50 +- .../frameworks/js/napi/preferences/BUILD.gn | 3 +- .../preferences/include/napi_preferences.h | 17 +- .../napi/preferences/src/napi_preferences.cpp | 238 ++--- .../src/napi_preferences_helper.cpp | 195 ++-- .../frameworks/js/napi/storage/BUILD.gn | 2 +- .../js/napi/storage/src/napi_storage.cpp | 107 +- .../napi/storage/src/napi_storage_helper.cpp | 47 +- .../js/napi/system_storage/BUILD.gn | 2 +- .../src/napi_system_storage.cpp | 37 +- .../include/data_preferences_observer_stub.h | 41 + .../include/data_preferences_observer_stub.h | 59 ++ .../src/data_preferences_observer_stub.cpp | 79 ++ .../native/common/mock/src/filelock.cpp | 39 + .../common/mock/src/preferences_thread.cpp | 23 + .../src/data_preferences_observer_stub.cpp | 40 + .../frameworks/native/include/adaptor.h | 7 +- .../frameworks/native/include/executor.h | 140 +++ .../frameworks/native/include/executor_pool.h | 225 +++++ .../frameworks/native/include/filelock.h | 35 + preferences/frameworks/native/include/pool.h | 140 +++ .../native/include/preferences_impl.h | 43 +- .../native/include/preferences_thread.h | 27 + .../native/include/priority_queue.h | 169 ++++ .../frameworks/native/src/filelock.cpp | 86 ++ .../native/src/preferences_helper.cpp | 31 +- .../native/src/preferences_impl.cpp | 192 ++-- .../native/src/preferences_thread.cpp | 23 + preferences/interfaces/inner_api/BUILD.gn | 56 +- .../inner_api/include/preferences.h | 26 +- .../inner_api/include/preferences_errno.h | 56 +- .../inner_api/include/preferences_helper.h | 5 +- .../inner_api/include/preferences_observer.h | 3 +- preferences/test/js/BUILD.gn | 8 + .../js/performance/preferences/src/BUILD.gn | 29 + .../PreferencesInstanceCallBackJsPref.test.js | 252 +++++ .../PreferencesInstancePromiseJsPref.test.js | 173 ++++ .../src/PreferencesInstanceSyncJsPref.test.js | 76 ++ ...PreferencesOperationCallBackJsPref.test.js | 138 +++ .../PreferencesOperationPromiseJsPref.test.js | 106 ++ .../PreferencesOperationSyncJsPref.test.js | 107 ++ .../performance/preferences/src/config.json | 63 ++ .../preferences/src/openharmony_sx.p7b | Bin 0 -> 3437 bytes .../src/PreferencesHelperJsunit.test.js | 194 +++- .../js/unittest/preferences/src/config.json | 1 + .../test/js/unittest/storage/src/config.json | 1 + .../unittest/system_storage/src/config.json | 1 + preferences/test/native/BUILD.gn | 6 +- .../fuzztest/preferences_fuzzer/BUILD.gn | 4 +- .../native/unittest/preferences_file_test.cpp | 35 +- relational_store/CMakeLists.txt | 3 + relational_store/CODEOWNERS | 17 + relational_store/bundle.json | 11 +- .../js/napi/cloud_data/include/js_config.h | 2 +- .../js/napi/cloud_data/src/js_config.cpp | 1 + .../cloud_data/src/js_const_properties.cpp | 1 + .../js/napi/cloud_data/src/napi_queue.cpp | 6 +- .../js/napi/common/include/js_ability.h | 6 +- .../js/napi/common/mock/include/js_ability.h | 5 +- .../js/napi/common/mock/src/js_ability.cpp | 22 +- .../js/napi/common/src/js_ability.cpp | 19 +- .../js/napi/common/src/js_utils.cpp | 2 +- .../js/napi/common/src/js_uv_queue.cpp | 2 - .../include/napi_data_ability_predicates.h | 2 +- .../include/napi_predicates_utils.h | 7 + .../src/napi_data_ability_predicates.cpp | 174 +++- .../js/napi/rdb/include/napi_rdb_error.h | 32 +- .../js/napi/rdb/include/napi_result_set.h | 10 +- .../js/napi/rdb/src/napi_async_call.cpp | 5 +- .../js/napi/rdb/src/napi_rdb_predicates.cpp | 144 ++- .../js/napi/rdb/src/napi_rdb_store.cpp | 84 +- .../js/napi/rdb/src/napi_rdb_store_helper.cpp | 6 +- .../napi/rdb/src/napi_rdb_store_observer.cpp | 4 + .../js/napi/rdb/src/napi_result_set.cpp | 69 +- .../relationalstore/include/napi_rdb_error.h | 9 + .../include/napi_rdb_predicates.h | 2 + .../relationalstore/include/napi_rdb_store.h | 20 +- .../include/napi_rdb_store_observer.h | 2 + .../mock/include/napi_rdb_predicates.h | 2 + .../mock/include/napi_rdb_store.h | 2 + .../src/napi_rdb_const_properties.cpp | 17 + .../relationalstore/src/napi_rdb_js_utils.cpp | 5 +- .../src/napi_rdb_predicates.cpp | 48 +- .../relationalstore/src/napi_rdb_store.cpp | 299 +++--- .../src/napi_rdb_store_helper.cpp | 99 +- .../src/napi_rdb_store_observer.cpp | 5 + .../relationalstore/src/napi_result_set.cpp | 2 +- .../relationalstore/src/napi_uv_queue.cpp | 3 + .../native/appdatafwk/src/general_endian.cpp | 2 - .../native/appdatafwk/src/shared_block.cpp | 4 + .../src/data_ability_predicates.cpp | 2 +- .../src/ishared_result_set_proxy.cpp | 2 +- .../native/rdb/include/rdb_service_proxy.h | 2 +- .../native/rdb/include/rdb_store_impl.h | 52 + .../native/rdb/include/sqlite_connection.h | 3 +- .../native/rdb/include/sqlite_sql_builder.h | 9 - .../native/rdb/include/step_result_set.h | 1 - .../native/rdb/include/string_utils.h | 4 +- .../rdb/mock/include/sqlite_sql_builder.h | 9 - .../native/rdb/mock/include/string_utils.h | 4 +- .../native/rdb/src/abs_predicates.cpp | 216 ++-- .../native/rdb/src/abs_rdb_predicates.cpp | 22 +- .../native/rdb/src/abs_result_set.cpp | 4 +- .../native/rdb/src/abs_shared_result_set.cpp | 78 +- .../native/rdb/src/rdb_predicates.cpp | 25 +- .../native/rdb/src/rdb_service_proxy.cpp | 11 +- .../native/rdb/src/rdb_sql_utils.cpp | 29 +- .../native/rdb/src/rdb_store_config.cpp | 10 + .../native/rdb/src/rdb_store_impl.cpp | 212 +++- .../native/rdb/src/rdb_store_manager.cpp | 8 +- .../native/rdb/src/security_policy.cpp | 6 +- .../native/rdb/src/sqlite_connection.cpp | 11 +- .../rdb/src/sqlite_shared_result_set.cpp | 8 - .../native/rdb/src/sqlite_sql_builder.cpp | 193 +--- .../native/rdb/src/step_result_set.cpp | 19 +- .../native/rdb/src/string_utils.cpp | 11 +- .../src/data_share_profile_info.cpp | 3 + .../include/data_ability_predicates.h | 2 +- .../interfaces/inner_api/rdb/BUILD.gn | 36 +- .../inner_api/rdb/include/abs_predicates.h | 59 +- .../rdb/include/abs_rdb_predicates.h | 18 +- .../rdb/include/abs_shared_result_set.h | 12 +- .../inner_api/rdb/include/rdb_errno.h | 10 + .../inner_api/rdb/include/rdb_predicates.h | 24 +- .../inner_api/rdb/include/rdb_service.h | 2 +- .../inner_api/rdb/include/rdb_store.h | 8 +- .../inner_api/rdb/include/rdb_store_config.h | 11 + .../inner_api/rdb/include/rdb_types.h | 15 + .../inner_api/rdb/include/shared_result_set.h | 2 +- .../rdb/mock/include/abs_rdb_predicates.h | 10 +- .../rdb/mock/include/rdb_predicates.h | 16 +- .../inner_api/rdb/mock/include/rdb_store.h | 5 + .../rdb/mock/include/rdb_store_config.h | 8 +- .../include/data_share_profile_info.h | 3 + .../rdb_data_ability_adapter/BUILD.gn | 10 +- relational_store/interfaces/ndk/BUILD.gn | 28 - .../interfaces/ndk/include/oh_cursor.h | 4 +- .../interfaces/ndk/include/oh_predicates.h | 2 +- .../interfaces/ndk/include/oh_value_object.h | 2 +- .../interfaces/ndk/include/oh_values_bucket.h | 2 +- .../interfaces/ndk/include/relational_store.h | 61 +- relational_store/interfaces/ndk/src/BUILD.gn | 43 + .../interfaces/ndk/src/relational_cursor.cpp | 188 ++-- .../interfaces/ndk/src/relational_cursor.h | 48 + .../ndk/src/relational_predicates.cpp | 495 +++++----- .../ndk/src/relational_predicates.h | 63 ++ .../ndk/src/relational_predicates_objects.cpp | 114 +++ .../ndk/src/relational_predicates_objects.h | 40 + .../interfaces/ndk/src/relational_store.cpp | 197 ++-- .../ndk/src/relational_store_impl.h | 10 +- .../ndk/src/relational_values_bucket.cpp | 125 ++- .../ndk/src/relational_values_bucket.h | 42 + relational_store/relational_store.gni | 2 +- .../test/js/clouddata/unittest/config.json | 2 +- .../unittest/src/CloudSyncConfigCallback.js | 160 ++- .../unittest/src/CloudSyncConfigPromise.js | 51 + .../test/js/dataability/unittest/config.json | 1 + .../test/js/rdb/performance/config.json | 1 + .../js/rdb/performance/src/PredicatestPerf.js | 2 +- .../performance/src/RdbHelperCallbackPerf.js | 2 +- .../performance/src/RdbHelperPromisePerf.js | 2 +- .../performance/src/RdbStoreCallbackPerf.js | 2 +- .../src/RdbStoreOthersCallbackPerf.js | 2 +- .../performance/src/RdbStorePromisePerf.js | 2 +- .../rdb/performance/src/RdbStoreSyncPerf.js | 2 +- .../js/rdb/performance/src/ResultSetPerf.js | 2 +- .../test/js/rdb/unittest/config.json | 1 + .../relationalstore/performance/config.json | 1 + .../js/relationalstore/unittest/config.json | 1 + .../src/RdbStoreAssetResultSetJsunit.test.js | 4 +- .../unittest/src/RdbStoreCloudSync.test.js | 427 ++++++++ ...reBackupRestoreWithFAContextJsunit.test.js | 58 +- .../unittest/src/RdbstoreInsertJsunit.test.js | 39 +- .../src/RdbstorePredicatesJsunit.test.js | 40 + .../src/RdbstorePromiseJsunit.test.js | 60 +- .../unittest/src/RdbstoreUpdateJsunit.test.js | 37 +- .../test/native/dataability/BUILD.gn | 5 +- relational_store/test/native/rdb/BUILD.gn | 2 + .../rdb_store_impl_test/BUILD.gn | 8 +- .../rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn | 2 + .../rdbstore_fuzzer/rdbstore_fuzzer.cpp | 285 +++--- .../native/rdb/unittest/rdb_helper_test.cpp | 1 + .../rdb/unittest/rdb_predicates_join_test.cpp | 120 ++- .../rdb/unittest/rdb_predicates_test.cpp | 616 +++++++++++- .../rdb_sqlite_shared_result_set_test.cpp | 224 +++++ .../rdb/unittest/rdb_step_result_set_test.cpp | 195 +++- .../rdb/unittest/rdb_store_config_test.cpp | 15 + .../rdb/unittest/rdb_store_subscribe_test.cpp | 44 + .../test/native/rdb_bms_adapter/BUILD.gn | 6 +- .../native/rdb_data_ability_adapter/BUILD.gn | 6 +- .../unittest/data_ability_utils_test.cpp | 2 +- .../native/rdb_data_share_adapter/BUILD.gn | 2 +- relational_store/test/ndk/BUILD.gn | 2 +- relational_store/test/ndk/unittest/common.h | 2 +- .../test/ndk/unittest/rdb_cursor_test.cpp | 46 +- .../test/ndk/unittest/rdb_predicates_test.cpp | 126 +-- .../test/ndk/unittest/rdb_store_test.cpp | 96 +- udmf/CMakeLists.txt | 8 +- udmf/framework/common/tlv_object.h | 5 +- udmf/framework/common/tlv_util.cpp | 20 +- .../innerkitsimpl/data/unified_data.cpp | 9 + .../test/unittest/udmf_client_test.cpp | 5 +- .../jskitsimpl/common/napi_data_utils.cpp | 2 +- .../jskitsimpl/unittest/UdmfCallbackJsTest.js | 2 +- .../framework/service/udmf_service_client.cpp | 25 + udmf/framework/service/udmf_service_client.h | 11 +- udmf/interfaces/innerkits/common/error_code.h | 17 + .../innerkits/common/unified_types.h | 1 + udmf/interfaces/innerkits/data/unified_data.h | 1 + 795 files changed, 33254 insertions(+), 7451 deletions(-) create mode 100644 data_object/CODEOWNERS create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_flat_object_watcher.h create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_object_watcher.h create mode 100644 data_share/frameworks/native/proxy/include/ams_mgr_proxy.h create mode 100644 data_share/frameworks/native/proxy/include/idata_share_client_death_observer.h create mode 100644 data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp create mode 100644 data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp create mode 100644 data_share/interfaces/inner_api/common/include/datashare_operation_statement.h create mode 100644 datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp create mode 100644 datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.cpp rename datamgr_service/services/distributeddataservice/service/{rdb/rdb_store_observer_impl.cpp => data_share/common/base64_utils.h} (49%) create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp delete mode 100644 datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp delete mode 100644 datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp create mode 100644 kv_store/CODEOWNERS create mode 100644 kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/BUILD.gn create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.h create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/corpus/init create mode 100644 kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/project.xml create mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/mock_sqlite_single_ver_natural_store.h create mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h create mode 100644 mock/innerkits/ability_runtime/extension_manager/include/extension_manager_client.h create mode 100644 mock/innerkits/ability_runtime/extension_manager/include/extension_manager_interface.h create mode 100644 mock/innerkits/ability_runtime/extension_manager/include/extension_manager_proxy.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/backup_extension_ability.js create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/file_share_sandbox.json create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/include/common_func.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/include/json_utils.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/include/log.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/include/sandbox_helper.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/src/common_func.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/src/json_utils.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/common/src/sandbox_helper.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_file_info.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/svc_death_recipient.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/include/file_share.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/src/file_share.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include/file_uri.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/src/file_uri.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include/remote_file_share.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/src/remote_file_share.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/general_callbacks.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/module.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.cpp rename datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h => mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.h (50%) create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.h create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.h create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/include/tools_op.h create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/main.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_backup.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_check_sa.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_help.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore_async.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/BUILD.gn create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_encryption/b_encryption.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_error.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_excep_utils.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_dir.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_file.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_hilog/filemgmt_libhilog.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_cached_entity.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_caps.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_ext_manage.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_extension_config.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_ohos/startup/backup_para.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_cwd.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_signal.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_multiuser.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_process.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_resources/b_constants.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_cmdline.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_factory.h create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/rust/src/lib.rs create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_encryption/b_encryption.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_error.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_excep_utils.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_dir.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_file.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_ipc/b_want_2_ext.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_ext_manage.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_extension_config.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_ohos/startup/backup_para.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_cwd.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_signal.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_process.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_cmdline.cpp create mode 100644 mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_factory.cpp create mode 100644 mock/innerkits/filemanagement/file_api/interfaces/kits/security_label.h delete mode 100644 mock/innerkits/netmanager_base/BUILD.gn create mode 100644 mock/innerkits/netmanager_base/innerkits/include/inet_addr.h create mode 100644 mock/innerkits/netmanager_base/innerkits/include/net_manager_constants.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/BUILD.gn create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/connect_blocklist.txt create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/http_proxy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_all_capabilities.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_client.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_constants.h rename mock/innerkits/netmanager_base/{net_stats_manager_if/include/net_stats_client.h => innerkits/netconnclient/include/net_handle.h} (34%) create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_interface_config.h rename mock/innerkits/netmanager_base/{net_conn_manager_if => innerkits/netconnclient}/include/net_link_info.h (80%) rename mock/innerkits/netmanager_base/{net_conn_manager_if => innerkits/netconnclient}/include/net_specifier.h (91%) rename mock/innerkits/netmanager_base/{net_stats_manager_if/include/net_stats_info.h => innerkits/netconnclient/include/net_supplier_callback_base.h} (55%) rename mock/innerkits/netmanager_base/{net_conn_manager_if => innerkits/netconnclient}/include/net_supplier_info.h (91%) create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/conn_ipc_interface_code.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_service.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_service.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_detection_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_interface_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_supplier_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_callback_stub.h rename mock/innerkits/netmanager_base/{net_conn_manager_if/include/net_conn_client.h => innerkits/netconnclient/include/proxy/net_conn_service_proxy.h} (30%) create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_detection_callback_stub.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_interface_callback_stub.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_supplier_callback_stub.h rename mock/innerkits/netmanager_base/{net_conn_manager_if => innerkits/netconnclient}/include/route.h (88%) create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/include/socket_permission.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netconnclient/libnetconn_kits.map create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/BUILD.gn create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/dhcp_result_parcel.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark_command.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_netsys_service.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_notify_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/interface_type.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/iptables_type.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netnative_log_wrapper.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_addr_info_parcel.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_ipc_interface_code.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_native_service_proxy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_permission.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_sharing.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_proxy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_stub.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/route_type.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netmanagernative/include/uid_range.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/BUILD.gn create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_client.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_constants.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_quota_policy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_service.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_callback_stub.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_service_proxy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/policy_ipc_interface_code.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netpolicyclient/libnetpolicy_kits.map create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/BUILD.gn create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/data_flow_statistics.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_client.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_constants.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_info.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_callback.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_service.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_callback_stub.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_service_proxy.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/stats_ipc_interface_code.h create mode 100644 mock/innerkits/netmanager_base/innerkits/netstatsclient/libnetstats_kits.map delete mode 100644 mock/innerkits/netmanager_base/net_policy_manager_if/include/net_policy_client.h delete mode 100644 mock/innerkits/netmanager_base/sdk_info.json create mode 100644 mock/src/mock_filemanagement.cpp create mode 100644 mock/src/mock_netmanager.cpp create mode 100644 preferences/frameworks/native/common/include/data_preferences_observer_stub.h create mode 100644 preferences/frameworks/native/common/mock/include/data_preferences_observer_stub.h create mode 100644 preferences/frameworks/native/common/mock/src/data_preferences_observer_stub.cpp create mode 100644 preferences/frameworks/native/common/mock/src/filelock.cpp create mode 100644 preferences/frameworks/native/common/mock/src/preferences_thread.cpp create mode 100644 preferences/frameworks/native/common/src/data_preferences_observer_stub.cpp create mode 100644 preferences/frameworks/native/include/executor.h create mode 100644 preferences/frameworks/native/include/executor_pool.h create mode 100644 preferences/frameworks/native/include/filelock.h create mode 100644 preferences/frameworks/native/include/pool.h create mode 100644 preferences/frameworks/native/include/preferences_thread.h create mode 100644 preferences/frameworks/native/include/priority_queue.h create mode 100644 preferences/frameworks/native/src/filelock.cpp create mode 100644 preferences/frameworks/native/src/preferences_thread.cpp create mode 100644 preferences/test/js/performance/preferences/src/BUILD.gn create mode 100644 preferences/test/js/performance/preferences/src/PreferencesInstanceCallBackJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/PreferencesInstancePromiseJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/PreferencesInstanceSyncJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/PreferencesOperationCallBackJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/PreferencesOperationPromiseJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/PreferencesOperationSyncJsPref.test.js create mode 100644 preferences/test/js/performance/preferences/src/config.json create mode 100644 preferences/test/js/performance/preferences/src/openharmony_sx.p7b create mode 100644 relational_store/CODEOWNERS create mode 100644 relational_store/interfaces/ndk/src/BUILD.gn create mode 100644 relational_store/interfaces/ndk/src/relational_cursor.h create mode 100644 relational_store/interfaces/ndk/src/relational_predicates.h create mode 100644 relational_store/interfaces/ndk/src/relational_predicates_objects.cpp create mode 100644 relational_store/interfaces/ndk/src/relational_predicates_objects.h create mode 100644 relational_store/interfaces/ndk/src/relational_values_bucket.h create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js diff --git a/data_object/CODEOWNERS b/data_object/CODEOWNERS new file mode 100644 index 00000000..43732bc4 --- /dev/null +++ b/data_object/CODEOWNERS @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# any change to +# frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h +# needs to be reviewed by @leonchan5 +frameworks/innerkitsimpl/include/distributeddata_object_store_ipc_interface_code.h @leonchan5 \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h index 1db679ce..b8007465 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/distributed_objectstore_impl.h @@ -21,7 +21,7 @@ #include #include "distributed_objectstore.h" - +#include "flat_object_store.h" namespace OHOS::ObjectStore { class WatcherProxy; enum SyncStatus { diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_handler.h b/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_handler.h index f7e43909..eb025774 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_handler.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_handler.h @@ -38,8 +38,8 @@ public: // stop DataChangeListener to watch data change; Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, + const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); int CreateSessionServer(const std::string &sessionName) const; diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_mgr.h b/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_mgr.h index 493e7075..64d14ee8 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_mgr.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/app_pipe_mgr.h @@ -41,8 +41,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, + const MessageInfo &info); // start server Status Start(const PipeInfo &pipeInfo); // stop server diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/app_types.h b/data_object/frameworks/innerkitsimpl/include/communicator/app_types.h index 28fd9484..ea02e192 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/app_types.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/app_types.h @@ -53,6 +53,27 @@ struct DeviceId { std::string deviceId; }; +enum RouteType : int32_t { + INVALID_ROUTE_TYPE = -1, + ROUTE_TYPE_ALL = 0, + WIFI_STA = 1, + WIFI_P2P = 2, + BT_BR = 3, + BT_BLE = 4, + BUTT = 5, +}; + +enum RecOperate : int32_t { + KEEP, + CHANGE_TO_P2P, + CHANGE_TO_BLUETOOTH, +}; + +struct DataInfo { + uint8_t *data; + uint32_t length; +}; + // app_distributed_data_manager using sub error code 0 constexpr ErrCode APP_DISTRIBUTEDDATAMGR_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, 0); diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider.h b/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider.h index 70fb9b96..14acf451 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider.h @@ -50,8 +50,8 @@ public: // Send data to other device, function will be called back after sent to notify send result KVSTORE_API - virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info = { MessageType::DEFAULT }) = 0; + virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &DataInfo, + uint32_t totalLength, const MessageInfo &info = { MessageType::DEFAULT }) = 0; // Get online deviceList KVSTORE_API virtual std::vector GetDeviceList() const = 0; diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider_impl.h b/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider_impl.h index ec22e088..6164e068 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/communication_provider_impl.h @@ -43,7 +43,7 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) override; // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &DataInfo, uint32_t totalLength, const MessageInfo &info) override; // Get online deviceList diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h b/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h index 65a92802..8f8ddaa7 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/process_communicator_impl.h @@ -42,6 +42,8 @@ public: KVSTORE_API DBStatus RegOnDataReceive(const OnDataReceive &callback) override; KVSTORE_API DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) override; + KVSTORE_API DBStatus SendData( + const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, uint32_t totalLength) override; KVSTORE_API uint32_t GetMtuSize() override; KVSTORE_API uint32_t GetMtuSize(const DeviceInfos &devInfo) override; KVSTORE_API DeviceInfos GetLocalDeviceInfos() override; diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h index 93d9fb48..d4b1940a 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h @@ -24,11 +24,11 @@ #include "app_data_change_listener.h" #include "app_device_status_change_listener.h" #include "app_types.h" +#include "concurrent_map.h" +#include "condition_lock.h" #include "session.h" #include "softbus_bus_center.h" -#include "condition_lock.h" #include "task_scheduler.h" -#include "concurrent_map.h" namespace OHOS { namespace ObjectStore { @@ -37,7 +37,7 @@ public: SoftBusAdapter(); ~SoftBusAdapter(); static std::shared_ptr GetInstance(); - + // add DeviceChangeListener to watch device change; Status StartWatchDeviceChange(const AppDeviceStatusChangeListener *observer, const PipeInfo &pipeInfo); // stop DeviceChangeListener to watch device change; @@ -58,8 +58,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, + const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); @@ -86,10 +86,20 @@ public: private: struct BytesMsg { uint8_t *ptr; - int size; - bool isSend; + uint32_t size; }; - std::shared_ptr> GetSemaphore (int32_t sessinId); + static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB + static constexpr uint32_t VECTOR_SIZE_THRESHOLD = 100; + static constexpr float SWITCH_DELAY_FACTOR = 0.6f; + Status CacheData(const std::string &deviceId, const DataInfo &dataInfo); + uint32_t GetSize(const std::string &deviceId); + RouteType GetRouteType(int sessionId); + RecOperate CalcRecOperate(uint32_t dataSize, RouteType currentRouteType, bool &isP2P) const; + void CacheSession(int32_t sessionId); + void DoSend(); + int GetDeviceId(int sessionId, std::string &deviceId); + int GetSessionId(const std::string &deviceId); + SessionAttribute GetSessionAttribute(bool isP2P); mutable std::mutex networkMutex_{}; mutable std::map networkId2Uuid_{}; DeviceInfo localInfo_{}; @@ -102,12 +112,30 @@ private: std::map busSessionMap_{}; bool flag_ = true; // only for br flag ISessionListener sessionListener_{}; - std::mutex statusMutex_ {}; - std::mutex sendDataMutex_ {}; - std::map>> sessionsStatus_; - ConcurrentMap> sessionsData_; + std::mutex statusMutex_{}; + std::mutex sendDataMutex_{}; + std::mutex mapLock_; + std::mutex deviceSessionLock_; + std::map sessionIds_; + std::mutex deviceDataLock_; + std::map> dataCaches_; std::shared_ptr taskQueue_; }; + +class AppDataListenerWrap { +public: + static void SetDataHandler(SoftBusAdapter *handler); + static int OnSessionOpened(int sessionId, int result); + static void OnSessionClosed(int sessionId); + static void OnMessageReceived(int sessionId, const void *data, unsigned int dataLen); + static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen); + +public: + // notifiy all listeners when received message + static void NotifyDataListeners( + const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); + static SoftBusAdapter *softBusAdapter_; +}; } // namespace ObjectStore } // namespace OHOS #endif /* DISTRIBUTEDDATAFWK_SRC_SOFTBUS_ADAPTER_H */ \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp index f47e6eda..0398e44b 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp @@ -112,7 +112,13 @@ sptr ObjectStoreDataServiceProxy::GetFeatureInterface(const std:: MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest(static_cast(KvStoreCode::GET_FEATURE_INTERFACE), data, reply, mo); + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERROR("SendRequest remote is nullptr."); + return nullptr; + } + int32_t error = + remote->SendRequest(static_cast(KvStoreCode::GET_FEATURE_INTERFACE), data, reply, mo); if (error != 0) { LOG_ERROR("SendRequest returned %{public}d", error); return nullptr; @@ -144,8 +150,13 @@ uint32_t ObjectStoreDataServiceProxy::RegisterClientDeathObserver( } MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest( - static_cast(KvStoreCode::REGISTERCLIENTDEATHOBSERVER), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("SendRequest remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(KvStoreCode::REGISTERCLIENTDEATHOBSERVER), data, reply, mo); if (error != 0) { LOG_WARN("failed during IPC. errCode %d", error); return ERR_IPC; 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 ab6501b9..e3c247fc 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp @@ -60,11 +60,7 @@ uint32_t DistributedObjectImpl::PutDouble(const std::string &key, double value) Type type = Type::TYPE_DOUBLE; PutNum(&type, 0, sizeof(type), data); PutNum(&value, sizeof(type), sizeof(value), data); - uint32_t status = flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::PutDouble setField err %{public}d", status); - } - return status; + return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); } uint32_t DistributedObjectImpl::PutBoolean(const std::string &key, bool value) @@ -74,11 +70,7 @@ uint32_t DistributedObjectImpl::PutBoolean(const std::string &key, bool value) Type type = Type::TYPE_BOOLEAN; PutNum(&type, 0, sizeof(type), data); PutNum(&value, sizeof(type), sizeof(value), data); - uint32_t status = flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::PutBoolean setField err %{public}d", status); - } - return status; + return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); } uint32_t DistributedObjectImpl::PutString(const std::string &key, const std::string &value) @@ -89,11 +81,7 @@ uint32_t DistributedObjectImpl::PutString(const std::string &key, const std::str PutNum(&type, 0, sizeof(type), data); Bytes dst = StringUtils::StrToBytes(value); data.insert(data.end(), dst.begin(), dst.end()); - uint32_t status = flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectImpl::PutString setField err %{public}d", status); - } - return status; + return flatObjectStore_->Put(sessionId_, FIELDS_PREFIX + key, data); } uint32_t DistributedObjectImpl::GetDouble(const std::string &key, double &value) 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 4743f88e..79662004 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 @@ -188,11 +188,7 @@ uint32_t DistributedObjectStoreImpl::SetStatusNotifier(std::shared_ptr watcherProxy = std::make_shared(notifier); - uint32_t status = flatObjectStore_->SetStatusNotifier(watcherProxy); - if (status != SUCCESS) { - LOG_ERROR("DistributedObjectStoreImpl::Watch failed %{public}d", status); - } - return status; + return flatObjectStore_->SetStatusNotifier(watcherProxy); } void DistributedObjectStoreImpl::NotifyCachedStatus(const std::string &sessionId) diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_handler.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_handler.cpp index d42b1d07..78da6b60 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_handler.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_handler.cpp @@ -34,10 +34,10 @@ AppPipeHandler::AppPipeHandler(const PipeInfo &pipeInfo) : pipeInfo_(pipeInfo) softbusAdapter_ = SoftBusAdapter::GetInstance(); } -Status AppPipeHandler::SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info) +Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - return softbusAdapter_->SendData(pipeInfo, deviceId, ptr, size, info); + return softbusAdapter_->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status AppPipeHandler::StartWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_mgr.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_mgr.cpp index 700d7ba2..b4f78f11 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_mgr.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/app_pipe_mgr.cpp @@ -54,15 +54,15 @@ Status AppPipeMgr::StopWatchDataChange(const AppDataChangeListener *observer, co } // Send data to other device, function will be called back after sent to notify send result. -Status AppPipeMgr::SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info) +Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - if (size > MAX_TRANSFER_SIZE || size <= 0 || ptr == nullptr || pipeInfo.pipeId.empty() - || deviceId.deviceId.empty()) { - LOG_WARN("Input is invalid, maxSize:%{public}d, current size:%{public}d", MAX_TRANSFER_SIZE, size); + if (dataInfo.length > MAX_TRANSFER_SIZE || dataInfo.length <= 0 || dataInfo.data == nullptr + || pipeInfo.pipeId.empty() || deviceId.deviceId.empty()) { + LOG_WARN("Input is invalid, maxSize:%{public}d, current size:%{public}u", MAX_TRANSFER_SIZE, dataInfo.length); return Status::ERROR; } - LOG_DEBUG("pipeInfo:%{public}s ,size:%{public}d", pipeInfo.pipeId.c_str(), size); + LOG_DEBUG("pipeInfo:%{public}s ,size:%{public}u", pipeInfo.pipeId.c_str(), dataInfo.length); std::shared_ptr appPipeHandler; { std::lock_guard lock(dataBusMapMutex_); @@ -73,7 +73,7 @@ Status AppPipeMgr::SendData( } appPipeHandler = it->second; } - return appPipeHandler->SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeHandler->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } // start server diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/communication_provider_impl.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/communication_provider_impl.cpp index 95f94f36..9a585cf1 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/communication_provider_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/communication_provider_impl.cpp @@ -68,10 +68,10 @@ Status CommunicationProviderImpl::StopWatchDataChange(const AppDataChangeListene return appPipeMgr_.StopWatchDataChange(observer, pipeInfo); } -Status CommunicationProviderImpl::SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info) +Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { - return appPipeMgr_.SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeMgr_.SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status CommunicationProviderImpl::Start(const PipeInfo &pipeInfo) diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp index 05265887..2745a200 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp @@ -103,11 +103,19 @@ DBStatus ProcessCommunicatorImpl::RegOnDataReceive(const OnDataReceive &callback } DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) +{ + uint32_t totalLength = 0; + return SendData(dstDevInfo, data, length, totalLength); +} + +DBStatus ProcessCommunicatorImpl::SendData( + const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, uint32_t totalLength) { PipeInfo pi = { thisProcessLabel_ }; + const DataInfo dataInfo = { const_cast(data), length }; DeviceId destination; destination.deviceId = dstDevInfo.identifier; - Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, data, static_cast(length)); + Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); if (errCode != Status::SUCCESS) { LOG_ERROR("commProvider_ SendData Fail."); return DBStatus::DB_ERROR; 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 dea59211..39addbc8 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp @@ -18,13 +18,13 @@ #include #include +#include "dev_manager.h" #include "kv_store_delegate_manager.h" #include "process_communicator_impl.h" #include "securec.h" #include "session.h" #include "softbus_adapter.h" #include "softbus_bus_center.h" -#include "dev_manager.h" namespace OHOS { namespace ObjectStore { @@ -33,30 +33,15 @@ constexpr int32_t END_SIZE = 3; constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; constexpr const char *REPLACE_CHAIN = "***"; constexpr const char *DEFAULT_ANONYMOUS = "******"; -constexpr int32_t INVALID_SESSIONID = -1; constexpr int32_t SOFTBUS_OK = 0; constexpr int32_t SOFTBUS_ERR = 1; constexpr int32_t INVALID_SESSION_ID = -1; constexpr int32_t SESSION_NAME_SIZE_MAX = 65; constexpr int32_t DEVICE_ID_SIZE_MAX = 65; constexpr size_t TASK_CAPACITY_MAX = 15; +constexpr int32_t SELF_SIDE = 1; using namespace std; - -class AppDataListenerWrap { -public: - static void SetDataHandler(SoftBusAdapter *handler); - static int OnSessionOpened(int sessionId, int result); - static void OnSessionClosed(int sessionId); - static void OnMessageReceived(int sessionId, const void *data, unsigned int dataLen); - static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen); - -public: - // notifiy all listeners when received message - static void NotifyDataListeners( - const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); - static SoftBusAdapter *softBusAdapter_; -}; SoftBusAdapter *AppDataListenerWrap::softBusAdapter_; std::shared_ptr SoftBusAdapter::instance_; @@ -78,6 +63,8 @@ SoftBusAdapter::~SoftBusAdapter() taskQueue_->Clean(); taskQueue_ = nullptr; } + dataCaches_.clear(); + sessionIds_.clear(); } Status SoftBusAdapter::StartWatchDeviceChange( @@ -362,113 +349,207 @@ Status SoftBusAdapter::StopWatchDataChange( return Status::ERROR; } -Status SoftBusAdapter::SendData( - const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, const MessageInfo &info) +RecOperate SoftBusAdapter::CalcRecOperate(uint32_t dataSize, RouteType currentRouteType, bool &isP2P) const { - lock_guard lock(sendDataMutex_); - uint8_t *tempCopied = new uint8_t[size]; - if (tempCopied == nullptr) { + if (currentRouteType == RouteType::WIFI_STA) { + return KEEP; + } + if (currentRouteType == RouteType::INVALID_ROUTE_TYPE || currentRouteType == BT_BR || currentRouteType == BT_BLE) { + if (dataSize > P2P_SIZE_THRESHOLD) { + isP2P = true; + return CHANGE_TO_P2P; + } + } + if (currentRouteType == WIFI_P2P) { + if (dataSize < P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR) { + return CHANGE_TO_BLUETOOTH; + } + isP2P = true; + } + return KEEP; +} + +SessionAttribute SoftBusAdapter::GetSessionAttribute(bool isP2P) +{ + SessionAttribute attr; + attr.dataType = TYPE_BYTES; + // If the dataType is BYTES, the default strategy is wifi_5G > wifi_2.4G > BR, without P2P; + if (!isP2P) { + return attr; + } + + int index = 0; + attr.linkType[index++] = LINK_TYPE_WIFI_WLAN_5G; + attr.linkType[index++] = LINK_TYPE_WIFI_WLAN_2G; + attr.linkType[index++] = LINK_TYPE_WIFI_P2P; + attr.linkType[index++] = LINK_TYPE_BR; + attr.linkTypeNum = index; + return attr; +} + +Status SoftBusAdapter::CacheData(const std::string &deviceId, const DataInfo &dataInfo) +{ + uint8_t *data = new uint8_t[dataInfo.length]; + if (data == nullptr) { LOG_ERROR("[SendData] create buffer fail."); return Status::INVALID_ARGUMENT; } - if (memcpy_s(tempCopied, size, ptr, size) != EOK) { + if (memcpy_s(data, dataInfo.length, dataInfo.data, dataInfo.length) != EOK) { LOG_ERROR("[SendData] memcpy_s fail."); - delete[] tempCopied; + delete[] data; return Status::INVALID_ARGUMENT; } - BytesMsg bytesMsg = { tempCopied, size, false }; - sessionsData_.Compute(INVALID_SESSIONID, [&bytesMsg](const int key, std::vector &bytesList) { - LOG_DEBUG("[SendData] Insert invalid sessionId."); - bytesList.push_back(bytesMsg); - return true; - }); - SessionAttribute attr; - attr.dataType = TYPE_BYTES; - LOG_INFO("[SendData] to %{public}s ,session:%{public}s, size:%{public}d", ToBeAnonymous(deviceId.deviceId).c_str(), - pipeInfo.pipeId.c_str(), size); - int sessionId = OpenSession(pipeInfo.pipeId.c_str(), pipeInfo.pipeId.c_str(), ToNodeID(deviceId.deviceId).c_str(), - "GROUP_ID", &attr); - sessionsData_.Compute(sessionId, [&bytesMsg](const int key, std::vector &bytesList) { - if (bytesList.empty()) { - bytesList.push_back(bytesMsg); - return true; - } - bool isPushMsg = true; - for (auto it = bytesList.begin(); it != bytesList.end();) { - if (bytesMsg.ptr == it->ptr) { - isPushMsg = false; - } - if (it->isSend) { - it = bytesList.erase(it); - } else { - ++it; - } - } - if (isPushMsg) { - bytesList.push_back(bytesMsg); + BytesMsg bytesMsg = { data, dataInfo.length }; + lock_guard lock(deviceDataLock_); + auto deviceIdData = dataCaches_.find(deviceId); + if (deviceIdData == dataCaches_.end()) { + dataCaches_[deviceId] = { bytesMsg }; + } else { + deviceIdData->second.push_back(bytesMsg); + if (deviceIdData->second.size() > VECTOR_SIZE_THRESHOLD) { + deviceIdData->second.erase(deviceIdData->second.begin()); } - return true; - }); - sessionsData_.Erase(INVALID_SESSIONID); + } return Status::SUCCESS; } -void SoftBusAdapter::OnSessionOpen(int32_t sessionId, int32_t status) +uint32_t SoftBusAdapter::GetSize(const std::string &deviceId) { - if (status != SOFTBUS_OK) { - LOG_DEBUG("[OnSessionOpen] OpenSession failed"); - return; + uint32_t dataSize = 0; + lock_guard lock(deviceDataLock_); + auto it = dataCaches_.find(deviceId); + if (it == dataCaches_.end() || it->second.empty()) { + return dataSize; } - auto item = sessionsData_.Find(INVALID_SESSIONID); - if (item.first && !item.second.empty()) { - sessionsData_.Compute(sessionId, [item](const int key, std::vector &bytesList) { - LOG_DEBUG("[OnSessionOpen] replace invalid sessionId with valid sessionId"); - bytesList = item.second; - return true; - }); - sessionsData_.Erase(INVALID_SESSIONID); - } - auto task([this, sessionId]() { - sessionsData_.Compute(sessionId, [](const int key, std::vector &bytesList) { - for (auto &bytesMsg : bytesList) { - if (bytesMsg.isSend) { - continue; - } - LOG_INFO("[SendBytes] start,session id is %{public}d", key); - uint8_t *msgPtr = bytesMsg.ptr; - int size = bytesMsg.size; - int32_t ret = SendBytes(key, static_cast(msgPtr), size); + for (const auto &msg : it->second) { + dataSize += msg.size; + } + return dataSize; +} + +RouteType SoftBusAdapter::GetRouteType(int sessionId) +{ + RouteType routeType = RouteType::INVALID_ROUTE_TYPE; + int ret = GetSessionOption(sessionId, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + if (ret != SOFTBUS_OK) { + LOG_ERROR("getSessionOption failed, ret is %{public}d.", ret); + } + return routeType; +} + +Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) +{ + lock_guard lock(sendDataMutex_); + auto result = CacheData(deviceId.deviceId, dataInfo); + if (result != Status::SUCCESS) { + return result; + } + uint32_t dataSize = GetSize(deviceId.deviceId) + totalLength; + int sessionId = GetSessionId(deviceId.deviceId); + bool isP2P = false; + RouteType currentRouteType = GetRouteType(sessionId); + RecOperate recOperate = CalcRecOperate(dataSize, currentRouteType, isP2P); + if (recOperate != KEEP && sessionId != INVALID_SESSION_ID) { + LOG_INFO("close session : %{public}d, currentRouteType : %{public}d, recOperate : %{public}d", sessionId, + currentRouteType, recOperate); + CloseSession(sessionId); + } + SessionAttribute attr = GetSessionAttribute(isP2P); + OpenSession(pipeInfo.pipeId.c_str(), pipeInfo.pipeId.c_str(), ToNodeID(deviceId.deviceId).c_str(), + "GROUP_ID", &attr); + return Status::SUCCESS; +} + +void SoftBusAdapter::CacheSession(int32_t sessionId) +{ + std::string deviceId; + if (GetDeviceId(sessionId, deviceId) == SOFTBUS_OK) { + lock_guard lock(deviceSessionLock_); + sessionIds_[deviceId] = sessionId; + } +} + +void SoftBusAdapter::DoSend() +{ + auto task([this]() { + lock_guard lockSession(deviceSessionLock_); + for (auto &it : sessionIds_) { + if (it.second == INVALID_SESSION_ID) { + continue; + } + lock_guard lock(deviceDataLock_); + auto dataCache = dataCaches_.find(it.first); + if (dataCache == dataCaches_.end()) { + continue; + } + for (auto msg = dataCache->second.begin(); msg != dataCache->second.end();) { + auto &byteMsg = *msg; + int32_t ret = SendBytes(it.second, byteMsg.ptr, byteMsg.size); if (ret != SOFTBUS_OK) { - LOG_ERROR("[SendBytes] to %{public}d failed, ret:%{public}d.", key, ret); + LOG_ERROR("[SendBytes] to %{public}d failed, ret:%{public}d.", it.second, ret); } LOG_DEBUG("[SendBytes] delete msgPtr."); - delete[] msgPtr; - bytesMsg.isSend = true; + delete[] byteMsg.ptr; + msg = dataCache->second.erase(msg); } - return true; - }); + } }); - taskQueue_->Execute(std::move(task)); } -void SoftBusAdapter::OnSessionClose(int32_t sessionId) +int SoftBusAdapter::GetDeviceId(int sessionId, std::string &deviceId) +{ + char peerDevId[DEVICE_ID_SIZE_MAX] = ""; + int ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); + if (ret != SOFTBUS_OK) { + LOG_ERROR("get peerDeviceId failed, sessionId :%{public}d", sessionId); + return ret; + } + lock_guard lock(networkMutex_); + auto it = networkId2Uuid_.find(std::string(peerDevId)); + if (it != networkId2Uuid_.end()) { + deviceId = it->second; + } + return ret; +} + +int SoftBusAdapter::GetSessionId(const std::string &deviceId) +{ + lock_guard lock(deviceSessionLock_); + auto it = sessionIds_.find(deviceId); + if (it != sessionIds_.end()) { + return it->second; + } + return INVALID_SESSION_ID; +} + +void SoftBusAdapter::OnSessionOpen(int32_t sessionId, int32_t status) { - lock_guard lock(statusMutex_); - auto it = sessionsStatus_.find(sessionId); - if (it != sessionsStatus_.end()) { - it->second->Clear(); - sessionsStatus_.erase(it); + if (status != SOFTBUS_OK) { + LOG_DEBUG("[OnSessionOpen] OpenSession failed"); + return; + } + if (GetSessionSide(sessionId) != SELF_SIDE) { + return; } + CacheSession(sessionId); + DoSend(); } -std::shared_ptr> SoftBusAdapter::GetSemaphore(int32_t sessionId) +void SoftBusAdapter::OnSessionClose(int32_t sessionId) { - lock_guard lock(statusMutex_); - if (sessionsStatus_.find(sessionId) == sessionsStatus_.end()) { - sessionsStatus_.emplace(sessionId, std::make_shared>()); + std::string deviceId; + if (GetSessionSide(sessionId) != SELF_SIDE) { + return; } - return sessionsStatus_[sessionId]; + if (GetDeviceId(sessionId, deviceId) == SOFTBUS_OK) { + lock_guard lock(deviceSessionLock_); + if (sessionIds_.find(deviceId) != sessionIds_.end()) { + sessionIds_.erase(deviceId); + } + } + DoSend(); } bool SoftBusAdapter::IsSameStartedOnPeer( @@ -519,7 +600,7 @@ int SoftBusAdapter::RemoveSessionServerAdapter(const std::string &sessionName) c void SoftBusAdapter::InsertSession(const std::string &sessionName) { lock_guard lock(busSessionMutex_); - busSessionMap_.insert({sessionName, true}); + busSessionMap_.insert({ sessionName, true }); } void SoftBusAdapter::DeleteSession(const std::string &sessionName) @@ -616,7 +697,6 @@ void AppDataListenerWrap::OnSessionClosed(int sessionId) LOG_DEBUG("[SessionClosed] mySessionName:%{public}s, " "peerSessionName:%{public}s, peerDevId:%{public}s", mySessionName, peerSessionName, SoftBusAdapter::ToBeAnonymous(peerUuid).c_str()); - if (strlen(peerSessionName) < 1) { softBusAdapter_->DeleteSession(std::string(mySessionName) + peerUuid); } else { diff --git a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp index 8d23a238..9b57404d 100644 --- a/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp +++ b/data_object/frameworks/innerkitsimpl/src/object_service_proxy.cpp @@ -46,7 +46,12 @@ int32_t ObjectServiceProxy::ObjectStoreSave(const std::string &bundleName, const } MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest(static_cast(ObjectCode::OBJECTSTORE_SAVE), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("ObjectStoreSave remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_SAVE), data, reply, mo); if (error != 0) { ZLOGE("SendRequest returned %d", error); return ERR_IPC; @@ -70,7 +75,13 @@ int32_t ObjectServiceProxy::ObjectStoreRevokeSave( MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest(static_cast(ObjectCode::OBJECTSTORE_REVOKE_SAVE), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("ObjectStoreRevokeSave remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_REVOKE_SAVE), data, reply, mo); if (error != 0) { ZLOGE("SendRequest returned %d", error); return ERR_IPC; @@ -94,7 +105,13 @@ int32_t ObjectServiceProxy::ObjectStoreRetrieve( MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest(static_cast(ObjectCode::OBJECTSTORE_RETRIEVE), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("ObjectStoreRetrieve remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_RETRIEVE), data, reply, mo); if (error != 0) { ZLOGE("SendRequest returned %d", error); return ERR_IPC; @@ -118,8 +135,13 @@ int32_t ObjectServiceProxy::RegisterDataObserver(const std::string &bundleName, MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest( - static_cast(ObjectCode::OBJECTSTORE_REGISTER_OBSERVER), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("RegisterDataObserver remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_REGISTER_OBSERVER), data, reply, mo); if (error != 0) { ZLOGE("SendRequest returned %d", error); return ERR_IPC; @@ -142,8 +164,13 @@ int32_t ObjectServiceProxy::UnregisterDataChangeObserver(const std::string &bund MessageParcel reply; MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest( - static_cast(ObjectCode::OBJECTSTORE_UNREGISTER_OBSERVER), data, reply, mo); + sptr remoteObject = Remote(); + if (remoteObject == nullptr) { + LOG_ERROR("UnregisterDataChangeObserver remoteObject is nullptr."); + return ERR_IPC; + } + int32_t error = + remoteObject->SendRequest(static_cast(ObjectCode::OBJECTSTORE_UNREGISTER_OBSERVER), data, reply, mo); if (error != 0) { ZLOGE("SendRequest returned %d", error); return ERR_IPC; diff --git a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn index 4dc42eca..d0d548e4 100644 --- a/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/distributedtest/data_object_test/BUILD.gn @@ -39,7 +39,7 @@ ohos_distributedtest("DistributedTest") { "access_token:libtoken_setproc", "c_utils:utils", "dsoftbus:softbus_client", - "hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] @@ -60,7 +60,7 @@ ohos_distributedtest("DistributedTestAgent") { "access_token:libtoken_setproc", "c_utils:utils", "dsoftbus:softbus_client", - "hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_core", ] 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 be2e6b54..c4cf76e8 100644 --- a/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/fuzztest/objectstore_fuzzer/BUILD.gn @@ -37,7 +37,7 @@ ohos_fuzztest("ObjectStoreFuzzTest") { "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", ] - external_deps = [ "hilog_native:libhilog" ] + external_deps = [ "hilog:libhilog" ] } ############################################################################### diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn index e31f191f..af7d02e5 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn @@ -54,7 +54,7 @@ ohos_unittest("NativeObjectStoreTest") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", - "hilog_native:libhilog", + "hilog:libhilog", ] deps = [ diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_data_change_listener.h b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_data_change_listener.h index e903734e..e4876b5f 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_data_change_listener.h +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_data_change_listener.h @@ -21,8 +21,12 @@ namespace OHOS { namespace ObjectStore { class MockAppDataChangeListener : public AppDataChangeListener { - MOCK_CONST_METHOD4(OnMessage, - void(const DeviceInfo &info, const uint8_t *ptr, const int size, const PipeInfo &pipeInfo)); + void OnMessage(const DeviceInfo &info, const uint8_t *ptr, const int size, const PipeInfo &pipeInfo) const override + { + data = std::string(reinterpret_cast(ptr)); + } +public: + mutable std::string data; }; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_device_change_listener.h b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_device_change_listener.h index 09aff6e8..378534e9 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_device_change_listener.h +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_app_device_change_listener.h @@ -16,12 +16,71 @@ #define DATA_OBJECT_MOCK_APP_DEVICE_CHANGE_LISTENER_H #include -#include "app_device_status_change_listener.h" +#include +#include +#include + +#include "app_device_status_change_listener.h" namespace OHOS { namespace ObjectStore { class MockAppDeviceStatusChangeListener : public AppDeviceStatusChangeListener { - MOCK_CONST_METHOD2(OnDeviceChanged, void(const DeviceInfo &info, const DeviceChangeType &type)); +public: + MockAppDeviceStatusChangeListener() + { + } + void OnDeviceChanged(const DeviceInfo &info, const DeviceChangeType &type) const override + { + std::unique_lock lock(mutex_); + deviceInfo_ = info; + result_ = true; + cond_.notify_all(); + } + + void Wait() + { + std::unique_lock lock(mutex_); + if (!result_) { + cond_.wait(lock, [this] { return result_; }); + } + } + + bool Compare(const DeviceInfo &deviceInfo) + { + if (deviceInfo_.deviceId == "" && deviceInfo_.deviceName == deviceInfo.deviceName + && deviceInfo_.deviceType == deviceInfo.deviceType) { + return true; + } + return false; + } + +public: + mutable std::mutex mutex_; + mutable std::condition_variable cond_; + mutable bool result_; + mutable DeviceInfo deviceInfo_; +}; +class MockAppDeviceStatusChangeListenerLow : public MockAppDeviceStatusChangeListener { + ChangeLevelType GetChangeLevelType() const override + { + return ChangeLevelType::LOW; + } +}; + +class MockAppDeviceStatusChangeListenerHigh : public MockAppDeviceStatusChangeListener { +public: + ChangeLevelType GetChangeLevelType() const override + { + return ChangeLevelType::HIGH; + } +}; + +class MockAppDeviceStatusChangeListenerMin : public MockAppDeviceStatusChangeListener { +public: + ChangeLevelType GetChangeLevelType() const override + { + return ChangeLevelType::MIN; + } }; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_flat_object_watcher.h b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_flat_object_watcher.h new file mode 100644 index 00000000..7f7f2771 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_flat_object_watcher.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATA_OBJECT_MOCK_FLAT_OBJECT_WATCHER_H +#define DATA_OBJECT_MOCK_FLAT_OBJECT_WATCHER_H + +#include "flat_object_store.h" + +namespace OHOS { +namespace ObjectStore { +class MockFlatObjectWatcher : public FlatObjectWatcher { +public: + MockFlatObjectWatcher(const std::string &sessionId) : FlatObjectWatcher(sessionId) + { + } + void OnChanged(const std::string &sessionid, const std::vector &changedData) override + { + } +}; +} // namespace ObjectStore +} // namespace OHOS + +#endif // DATA_OBJECT_MOCK_FLAT_OBJECT_WATCHER_H diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_object_watcher.h b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_object_watcher.h new file mode 100644 index 00000000..6742cb50 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/include/mock_object_watcher.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DATA_OBJECT_MOCK_OBJECT_WATCHER_H +#define DATA_OBJECT_MOCK_OBJECT_WATCHER_H + +#include "distributed_object.h" + +namespace OHOS { +namespace ObjectStore { +class MockObjectWatcher : public ObjectWatcher { +public: + MockObjectWatcher() + { + } + virtual ~MockObjectWatcher() + { + } + void OnChanged(const std::string &sessionid, const std::vector &changedData) override + { + } +}; +} // namespace ObjectStore +} // namespace OHOS + +#endif // DATA_OBJECT_MOCK_OBJECT_WATCHER_H diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp index 9151c97a..e599f843 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp @@ -48,7 +48,7 @@ int RemoveSessionServer(const char *pkgName, const char *sessionName) } int GetMySessionName(int sessionId, char *sessionName, unsigned int len) { - return -1; + return 0; } int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len) { @@ -71,7 +71,9 @@ int32_t GetLocalNodeDeviceInfo(const char *pkgName, NodeBasicInfo *info) int32_t GetAllNodeDeviceInfo(const char *pkgName, NodeBasicInfo **info, int32_t *infoNum) { - return -1; + (*info) = (NodeBasicInfo *)malloc(sizeof(NodeBasicInfo)); + (*infoNum) = 1; + return 0; } int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, NodeDeviceInfoKey key, uint8_t *info, diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp index 5d2dc4f0..c5dbfcbe 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp @@ -13,16 +13,18 @@ * limitations under the License. */ +#include "app_pipe_mgr.h" + #include #include + #include -#include "app_pipe_mgr.h" #include "app_types.h" #include "auto_launch_export.h" #include "ipc_skeleton.h" -#include "objectstore_errors.h" #include "mock_app_data_change_listener.h" +#include "objectstore_errors.h" namespace { using namespace testing::ext; @@ -63,7 +65,7 @@ void NativeAppPipeMgrTest::TearDown(void) */ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StartWatchDataChange_001, TestSize.Level1) { - PipeInfo pipeInfo = {""}; + PipeInfo pipeInfo = { "" }; AppDataChangeListener *observer = new MockAppDataChangeListener(); AppPipeMgr *appPipeMgr = new AppPipeMgr(); auto ret = appPipeMgr->StartWatchDataChange(observer, pipeInfo); @@ -84,6 +86,35 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StartWatchDataChange_002, Te EXPECT_EQ(Status::ERROR, ret); } +/** + * @tc.name: NativeAppPipeMgrTest_StartWatchDataChange_003 + * @tc.desc: test NativeAppPipeMgrTest StartWatchDataChange. observer is nullptr. + * @tc.type: FUNC + */ +HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StartWatchDataChange_003, TestSize.Level1) +{ + PipeInfo pipeInfo = { "pipId01" }; + AppPipeMgr appPipeMgr; + auto ret = appPipeMgr.StartWatchDataChange(nullptr, pipeInfo); + EXPECT_EQ(Status::INVALID_ARGUMENT, ret); +} + +/** + * @tc.name: NativeAppPipeMgrTest_StartWatchDataChange_004 + * @tc.desc: test NativeAppPipeMgrTest StartWatchDataChange. the pipId can be found. + * @tc.type: FUNC + */ +HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StartWatchDataChange_004, TestSize.Level1) +{ + PipeInfo pipeInfo = { "pipId01" }; + AppPipeMgr appPipeMgr; + auto ret = appPipeMgr.Start(pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + MockAppDataChangeListener observer; + ret = appPipeMgr.StartWatchDataChange(&observer, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); +} + /** * @tc.name: NativeAppPipeMgrTest_StopWatchDataChange_001 * @tc.desc: test NativeAppPipeMgrTest StopWatchDataChange. argument invalid @@ -118,11 +149,15 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StopWatchDataChange_002, Tes */ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_StopWatchDataChange_003, TestSize.Level1) { - PipeInfo pipeInfo = { "pipId01" }; - AppPipeMgr *appPipeMgr = new AppPipeMgr(); - AppDataChangeListener *observer = new MockAppDataChangeListener(); - auto ret = appPipeMgr->StopWatchDataChange(observer, pipeInfo); - EXPECT_EQ(Status::ERROR, ret); + PipeInfo pipeInfo = { "pipId02" }; + AppPipeMgr appPipeMgr; + auto ret = appPipeMgr.Start(pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + MockAppDataChangeListener observer; + ret = appPipeMgr.StartWatchDataChange(&observer, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + ret = appPipeMgr.StopWatchDataChange(&observer, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); } /** @@ -145,7 +180,7 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_Start_001, TestSize.Level1) */ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_Start_002, TestSize.Level1) { - PipeInfo pipeInfo = {"INVALID_SESSION_NAME"}; + PipeInfo pipeInfo = { "INVALID_SESSION_NAME" }; AppPipeMgr *appPipeMgr = new AppPipeMgr(); auto ret = appPipeMgr->Start(pipeInfo); EXPECT_EQ(Status::ILLEGAL_STATE, ret); @@ -219,13 +254,38 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_Stop_002, TestSize.Level1) HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_SendData_001, TestSize.Level1) { PipeInfo pipeInfo = {}; - DeviceId deviceId = {"devideId01"}; - int size = 1; + DeviceId deviceId = { "devideId01" }; + uint32_t size = 1; uint8_t tmpNum = 1; uint8_t *ptr = &tmpNum; - MessageInfo messageInfo = {MessageType::DEFAULT}; - AppPipeMgr *appPipeMgr = new AppPipeMgr(); - auto ret = appPipeMgr->SendData(pipeInfo, deviceId, ptr, size, messageInfo); + const DataInfo dataInfo = { const_cast(ptr), size }; + MessageInfo messageInfo = { MessageType::DEFAULT }; + AppPipeMgr appPipeMgr; + // pipeInfo is empty + auto ret = appPipeMgr.SendData(pipeInfo, deviceId, dataInfo, size, messageInfo); + EXPECT_EQ(Status::ERROR, ret); + + // deviceId is empty + PipeInfo pipeInfo1 = { "pipeInfo" }; + DeviceId deviceId1 = { "" }; + ret = appPipeMgr.SendData(pipeInfo1, deviceId1, dataInfo, size, messageInfo); + EXPECT_EQ(Status::ERROR, ret); + + // dataInfo.length is less than or equal to 0 + DeviceId deviceId2 = { "devideId01" }; + const DataInfo dataInfo1 = { const_cast(ptr), 0 }; + ret = appPipeMgr.SendData(pipeInfo1, deviceId2, dataInfo1, size, messageInfo); + EXPECT_EQ(Status::ERROR, ret); + + // dataInfo.length exceeds limit + static const int MAX_TRANSFER_SIZE = 1024 * 1024 * 5; + const DataInfo dataInfo2 = { const_cast(ptr), MAX_TRANSFER_SIZE + 1 }; + ret = appPipeMgr.SendData(pipeInfo1, deviceId2, dataInfo2, size, messageInfo); + EXPECT_EQ(Status::ERROR, ret); + + // dataInfo.data is nullptr + const DataInfo dataInfo3 = { nullptr, size }; + ret = appPipeMgr.SendData(pipeInfo1, deviceId2, dataInfo3, size, messageInfo); EXPECT_EQ(Status::ERROR, ret); } @@ -236,17 +296,39 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_SendData_001, TestSize.Level */ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_SendData_002, TestSize.Level1) { - PipeInfo pipeInfo = {"pipInfo02"}; - DeviceId deviceId = {"devideId02"}; - int size = 1; + PipeInfo pipeInfo = { "pipInfo02" }; + DeviceId deviceId = { "devideId02" }; + uint32_t size = 1; uint8_t tmpNum = 1; uint8_t *ptr = &tmpNum; + const DataInfo dataInfo = { const_cast(ptr), size }; MessageInfo messageInfo = { MessageType::DEFAULT }; AppPipeMgr *appPipeMgr = new AppPipeMgr(); - auto ret = appPipeMgr->SendData(pipeInfo, deviceId, ptr, size, messageInfo); + auto ret = appPipeMgr->SendData(pipeInfo, deviceId, dataInfo, size, messageInfo); EXPECT_EQ(Status::KEY_NOT_FOUND, ret); } +/** + * @tc.name: NativeAppPipeMgrTest_SendData_003 + * @tc.desc: test NativeAppPipeMgrTest SendData. pipInfo not found + * @tc.type: FUNC + */ +HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_SendData_003, TestSize.Level1) +{ + PipeInfo pipeInfo = { "pipInfo02" }; + DeviceId deviceId = { "devideId02" }; + uint32_t size = 1; + uint8_t tmpNum = 1; + uint8_t *ptr = &tmpNum; + const DataInfo dataInfo = { const_cast(ptr), size }; + MessageInfo messageInfo = { MessageType::DEFAULT }; + AppPipeMgr appPipeMgr; + Status ret = appPipeMgr.Start(pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + ret = appPipeMgr.SendData(pipeInfo, deviceId, dataInfo, size, messageInfo); + EXPECT_EQ(Status::SUCCESS, ret); +} + /** * @tc.name: NativeAppPipeMgrTest_IsSameStartedOnPeer_001 * @tc.desc: test NativeAppPipeMgrTest IsSameStartedOnPeer. pipInfo or deviceId is empty @@ -269,10 +351,24 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_IsSameStartedOnPeer_001, Tes HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_IsSameStartedOnPeer_002, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo02" }; - DeviceId deviceId = {"deviceId02"}; + DeviceId deviceId = { "deviceId02" }; AppPipeMgr *appPipeMgr = new AppPipeMgr(); auto ret = appPipeMgr->IsSameStartedOnPeer(pipeInfo, deviceId); EXPECT_EQ(false, ret); } +/** + * @tc.name: NativeAppPipeMgrTest_IsSameStartedOnPeer_003 + * @tc.desc: test NativeAppPipeMgrTest IsSameStartedOnPeer. pipInfo not found + * @tc.type: FUNC + */ +HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_IsSameStartedOnPeer_003, TestSize.Level1) +{ + PipeInfo pipeInfo = { "pipInfo02" }; + DeviceId deviceId = { "deviceId02" }; + AppPipeMgr appPipeMgr; + appPipeMgr.Start(pipeInfo); + auto ret = appPipeMgr.IsSameStartedOnPeer(pipeInfo, deviceId); + EXPECT_EQ(false, ret); } +} // namespace diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp index 9a1d62d8..25f92cdc 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp @@ -47,6 +47,8 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); +public: + SoftBusAdapter softBusAdapter_; }; void NativeCommunicatorTest::SetUpTestCase(void) @@ -71,33 +73,29 @@ void NativeCommunicatorTest::TearDown(void) /** * @tc.name: SoftBusAdapter_StartWatchDeviceChange_001 - * @tc.desc: test SoftBusAdapter NotifyAll. + * @tc.desc: test SoftBusAdapter StartWatchDeviceChange. insert a normal observer * @tc.type: FUNC */ HWTEST_F(NativeCommunicatorTest, StartWatchDeviceChange_001, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo001" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener = new MockAppDeviceStatusChangeListener(); - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListener listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - delete softBusAdapter; - delete mockAppDeviceStatusChangeListener; } /** * @tc.name: SoftBusAdapter_StartWatchDeviceChange_002 - * @tc.desc: test SoftBusAdapter NotifyAll. input parameter of observer is null + * @tc.desc: test SoftBusAdapter StartWatchDeviceChange. inserted observer is null * @tc.type: FUNC */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDeviceChange_002, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo002" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener = nullptr; - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.StartWatchDeviceChange(nullptr, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; } /** @@ -108,14 +106,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDeviceChange_002, Test HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDeviceChange_003, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo003" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener = new MockAppDeviceStatusChangeListener(); - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListener listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; - delete mockAppDeviceStatusChangeListener; } /** @@ -126,14 +122,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDeviceChange_003, Test HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDeviceChange_001, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo001" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener = new MockAppDeviceStatusChangeListener(); - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListener listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - ret = softBusAdapter->StopWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + ret = softBusAdapter.StopWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - delete softBusAdapter; - delete mockAppDeviceStatusChangeListener; } /** @@ -144,14 +138,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDeviceChange_001, TestS HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDeviceChange_002, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo002" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener = new MockAppDeviceStatusChangeListener(); - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListener listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - ret = softBusAdapter->StopWatchDeviceChange(nullptr, pipeInfo); + ret = softBusAdapter.StopWatchDeviceChange(nullptr, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; - delete mockAppDeviceStatusChangeListener; } /** @@ -162,16 +154,70 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDeviceChange_002, TestS HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDeviceChange_003, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo003" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener1 = new MockAppDeviceStatusChangeListener(); - MockAppDeviceStatusChangeListener *mockAppDeviceStatusChangeListener2 = new MockAppDeviceStatusChangeListener(); - auto ret = softBusAdapter->StartWatchDeviceChange(mockAppDeviceStatusChangeListener1, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListener listener1; + MockAppDeviceStatusChangeListener listener2; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener1, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - ret = softBusAdapter->StopWatchDeviceChange(mockAppDeviceStatusChangeListener2, pipeInfo); + ret = softBusAdapter.StopWatchDeviceChange(&listener2, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; - delete mockAppDeviceStatusChangeListener1; - delete mockAppDeviceStatusChangeListener2; +} + +/** + * @tc.name: SoftBusAdapter_NotifyAll_001 + * @tc.desc: test SoftBusAdapter NotifyAll. input parameter of GetChangeLevelType is low + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_NotifyAll_001, TestSize.Level1) +{ + OHOS::ObjectStore::DeviceInfo deviceInfo = { "001", "localLow", "phoneLow" }; + PipeInfo pipeInfo = { "pipInfo001" }; + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListenerLow listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + + softBusAdapter.NotifyAll(deviceInfo, DeviceChangeType::DEVICE_ONLINE); + listener.Wait(); + EXPECT_EQ(listener.Compare(deviceInfo), true); +} + +/** + * @tc.name: SoftBusAdapter_NotifyAll_002 + * @tc.desc: test SoftBusAdapter NotifyAll. input parameter of GetChangeLevelType is high + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_NotifyAll_002, TestSize.Level1) +{ + OHOS::ObjectStore::DeviceInfo deviceInfo = { "001", "localHigh", "phoneHigh" }; + PipeInfo pipeInfo = { "pipInfo001" }; + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListenerHigh listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + + softBusAdapter.NotifyAll(deviceInfo, DeviceChangeType::DEVICE_ONLINE); + listener.Wait(); + EXPECT_EQ(listener.Compare(deviceInfo), true); +} + +/** + * @tc.name: SoftBusAdapter_NotifyAll_003 + * @tc.desc: test SoftBusAdapter NotifyAll. input parameter of GetChangeLevelType is min + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_NotifyAll_003, TestSize.Level1) +{ + OHOS::ObjectStore::DeviceInfo deviceInfo = { "001", "localMin", "phoneMin" }; + PipeInfo pipeInfo = { "pipInfo001" }; + SoftBusAdapter softBusAdapter; + MockAppDeviceStatusChangeListenerMin listener; + auto ret = softBusAdapter.StartWatchDeviceChange(&listener, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + + softBusAdapter.NotifyAll(deviceInfo, DeviceChangeType::DEVICE_ONLINE); + listener.Wait(); + EXPECT_EQ(listener.Compare(deviceInfo), true); } /** @@ -183,10 +229,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_IsSameStartedOnPeer_001, TestSiz { PipeInfo pipeInfo = { "pipInfo001" }; DeviceId deviceId = { "deviceId01" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->IsSameStartedOnPeer(pipeInfo, deviceId); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.IsSameStartedOnPeer(pipeInfo, deviceId); EXPECT_EQ(false, ret); - delete softBusAdapter; } /** @@ -198,13 +243,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_IsSameStartedOnPeer_002, TestSiz { PipeInfo pipeInfo = { "pipInfo002" }; DeviceId deviceId = { "deviceId02" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); + SoftBusAdapter softBusAdapter; std::string sessionName = "pipInfo002deviceId02"; - softBusAdapter->InsertSession(sessionName); - auto ret = softBusAdapter->IsSameStartedOnPeer(pipeInfo, deviceId); + softBusAdapter.InsertSession(sessionName); + auto ret = softBusAdapter.IsSameStartedOnPeer(pipeInfo, deviceId); EXPECT_EQ(true, ret); - softBusAdapter->DeleteSession(sessionName); - delete softBusAdapter; + softBusAdapter.DeleteSession(sessionName); } /** @@ -215,12 +259,10 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_IsSameStartedOnPeer_002, TestSiz HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_001, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo001" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - AppDataChangeListener *observer = new MockAppDataChangeListener(); - auto ret = softBusAdapter->StartWatchDataChange(observer, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDataChangeListener listener; + auto ret = softBusAdapter.StartWatchDataChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - delete softBusAdapter; - delete observer; } /** @@ -231,13 +273,11 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_001, TestSi HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_002, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo002" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - AppDataChangeListener *observer = new MockAppDataChangeListener(); - auto ret = softBusAdapter->StartWatchDataChange(observer, pipeInfo); - ret = softBusAdapter->StartWatchDataChange(observer, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDataChangeListener listener; + auto ret = softBusAdapter.StartWatchDataChange(&listener, pipeInfo); + ret = softBusAdapter.StartWatchDataChange(&listener, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; - delete observer; } /** @@ -248,10 +288,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_002, TestSi HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_003, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo002" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->StartWatchDataChange(nullptr, pipeInfo); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.StartWatchDataChange(nullptr, pipeInfo); EXPECT_EQ(Status::INVALID_ARGUMENT, ret); - delete softBusAdapter; } /** @@ -262,14 +301,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StartWatchDataChange_003, TestSi HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDataChange_001, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo001" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - AppDataChangeListener *observer = new MockAppDataChangeListener(); - auto ret = softBusAdapter->StartWatchDataChange(observer, pipeInfo); + SoftBusAdapter softBusAdapter; + MockAppDataChangeListener listener; + auto ret = softBusAdapter.StartWatchDataChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - softBusAdapter->StopWatchDataChange(observer, pipeInfo); + softBusAdapter.StopWatchDataChange(&listener, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - delete softBusAdapter; - delete observer; } /** @@ -280,10 +317,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDataChange_001, TestSiz HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDataChange_002, TestSize.Level1) { PipeInfo pipeInfo = { "pipInfo001" }; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->StopWatchDataChange(nullptr, pipeInfo); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.StopWatchDataChange(nullptr, pipeInfo); EXPECT_EQ(Status::ERROR, ret); - delete softBusAdapter; } /** @@ -294,10 +330,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_StopWatchDataChange_002, TestSiz HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_ToBeAnonymous_001, TestSize.Level1) { std::string name = "na"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->ToBeAnonymous(name); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.ToBeAnonymous(name); EXPECT_EQ(DEFAULT_ANONYMOUS, ret); - delete softBusAdapter; } /** @@ -308,10 +343,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_ToBeAnonymous_001, TestSize.Leve HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_ToBeAnonymous_002, TestSize.Level1) { std::string name = "name"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->ToBeAnonymous(name); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.ToBeAnonymous(name); EXPECT_EQ(name.substr(0, HEAD_SIZE) + REPLACE_CHAIN, ret); - delete softBusAdapter; } /** @@ -321,12 +355,11 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_ToBeAnonymous_002, TestSize.Leve */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalBasicInfo_001, TestSize.Level1) { - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->GetLocalBasicInfo(); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.GetLocalBasicInfo(); EXPECT_EQ(true, ret.deviceId.empty()); EXPECT_EQ(true, ret.deviceName.empty()); EXPECT_EQ(true, ret.deviceType.empty()); - delete softBusAdapter; } /** @@ -336,10 +369,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalBasicInfo_001, TestSize. */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalBasicInfo_002, TestSize.Level1) { - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->GetRemoteNodesBasicInfo(); - EXPECT_EQ(true, ret.empty()); - delete softBusAdapter; + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.GetRemoteNodesBasicInfo(); + EXPECT_EQ(false, ret.empty()); } /** @@ -350,12 +382,11 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalBasicInfo_002, TestSize. HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_001, TestSize.Level1) { std::string networdId01 = "networdId01"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); - auto ret = softBusAdapter->ToNodeID(""); + SoftBusAdapter softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + auto ret = softBusAdapter.ToNodeID(""); EXPECT_EQ(networdId01, ret); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); - delete softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); } /** @@ -367,14 +398,13 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_002, TestSize { std::string networdId01 = "networdId01"; std::string networdId02 = "networdId02"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); - softBusAdapter->UpdateRelationship(networdId02, DeviceChangeType::DEVICE_ONLINE); - softBusAdapter->UpdateRelationship(networdId02, DeviceChangeType::DEVICE_OFFLINE); - auto ret = softBusAdapter->ToNodeID(""); + SoftBusAdapter softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + softBusAdapter.UpdateRelationship(networdId02, DeviceChangeType::DEVICE_ONLINE); + softBusAdapter.UpdateRelationship(networdId02, DeviceChangeType::DEVICE_OFFLINE); + auto ret = softBusAdapter.ToNodeID(""); EXPECT_EQ(networdId01, ret); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); - delete softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); } /** @@ -386,13 +416,12 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_003, TestSize { std::string networdId01 = "networdId01"; std::string networdId02 = "networdId02"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); - auto ret = softBusAdapter->ToNodeID(""); + SoftBusAdapter softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + auto ret = softBusAdapter.ToNodeID(""); EXPECT_EQ(networdId01, ret); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); - delete softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); } /** @@ -404,13 +433,29 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_004, TestSize { std::string networdId01 = "networdId01"; std::string networdId02 = "networdId02"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); - softBusAdapter->UpdateRelationship(networdId02, DeviceChangeType::DEVICE_OFFLINE); - auto ret = softBusAdapter->ToNodeID(""); + SoftBusAdapter softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + softBusAdapter.UpdateRelationship(networdId02, DeviceChangeType::DEVICE_OFFLINE); + auto ret = softBusAdapter.ToNodeID(""); + EXPECT_EQ(networdId01, ret); + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); +} + +/** + * @tc.name: SoftBusAdapter_UpdateRelationship_005 + * @tc.desc: test SoftBusAdapter UpdateRelationship. The input parameter is an incorrect DeviceChangeType + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_005, TestSize.Level1) +{ + std::string networdId01 = "networdId01"; + std::string networdId02 = "networdId02"; + SoftBusAdapter softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_ONLINE); + softBusAdapter.UpdateRelationship(networdId02, static_cast(-1)); + auto ret = softBusAdapter.ToNodeID(""); EXPECT_EQ(networdId01, ret); - softBusAdapter->UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); - delete softBusAdapter; + softBusAdapter.UpdateRelationship(networdId01, DeviceChangeType::DEVICE_OFFLINE); } /** @@ -421,10 +466,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_UpdateRelationship_004, TestSize HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_RemoveSessionServerAdapter_001, TestSize.Level1) { std::string sessionName = "sessionName01"; - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->RemoveSessionServerAdapter(sessionName); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.RemoveSessionServerAdapter(sessionName); EXPECT_EQ(SUCCESS, ret); - delete softBusAdapter; } /** @@ -434,10 +478,9 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_RemoveSessionServerAdapter_001, */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetDeviceList_001, TestSize.Level1) { - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->GetDeviceList(); - EXPECT_EQ(true, ret.empty()); - delete softBusAdapter; + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.GetDeviceList(); + EXPECT_EQ(false, ret.empty()); } /** @@ -447,14 +490,99 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetDeviceList_001, TestSize.Leve */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalDevice_001, TestSize.Level1) { - SoftBusAdapter *softBusAdapter = new SoftBusAdapter(); - auto ret = softBusAdapter->GetLocalDevice(); + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.GetLocalDevice(); EXPECT_EQ(true, ret.deviceId.empty()); EXPECT_EQ(true, ret.deviceName.empty()); EXPECT_EQ(true, ret.deviceType.empty()); - delete softBusAdapter; } +/** + * @tc.name: SoftBusAdapter_SendData_001 + * @tc.desc: test SoftBusAdapter SendData. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_SendData_001, TestSize.Level1) +{ + PipeInfo pipeInfo = {}; + DeviceId deviceId = {"devideId01"}; + uint32_t size = 1; + uint8_t tmpNum = 1; + uint8_t *ptr = &tmpNum; + const DataInfo dataInfo = { const_cast(ptr), size }; + MessageInfo messageInfo = {MessageType::DEFAULT}; + SoftBusAdapter softBusAdapter; + auto ret = softBusAdapter.SendData(pipeInfo, deviceId, dataInfo, size, messageInfo); + EXPECT_EQ(Status::SUCCESS, ret); +} + +/** + * @tc.name: AppDataListenerWrap_OnSessionOpened_001 + * @tc.desc: test AppDataListenerWrap OnSessionOpened. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnSessionOpened_001, TestSize.Level1) +{ + int sessionId = 1; + int result = 0; + AppDataListenerWrap::SetDataHandler(&softBusAdapter_); + auto ret = AppDataListenerWrap::OnSessionOpened(sessionId, result); + EXPECT_EQ(0, ret); + AppDataListenerWrap::OnSessionClosed(sessionId); +} + +/** + * @tc.name: AppDataListenerWrap_OnSessionOpened_002 + * @tc.desc: test AppDataListenerWrap OnSessionOpened. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnSessionOpened_002, TestSize.Level1) +{ + int sessionId = 1; + int result = 1; + AppDataListenerWrap::SetDataHandler(&softBusAdapter_); + auto ret = AppDataListenerWrap::OnSessionOpened(sessionId, result); + EXPECT_EQ(1, ret); + AppDataListenerWrap::OnSessionClosed(sessionId); +} + +/** + * @tc.name: AppDataListenerWrap_OnMessageReceived_001 + * @tc.desc: test AppDataListenerWrap OnMessageReceived. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnMessageReceived_001, TestSize.Level1) +{ + PipeInfo pipeInfo = { "" }; + SoftBusAdapter softBusAdapter; + MockAppDataChangeListener observer; + auto ret = softBusAdapter.StartWatchDataChange(&observer, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + int sessionId = 1; + AppDataListenerWrap::SetDataHandler(&softBusAdapter); + std::string data = "OnMessageReceived"; + AppDataListenerWrap::OnMessageReceived(sessionId, reinterpret_cast(data.c_str()), data.size()); + EXPECT_EQ(data, observer.data); +} + +/** + * @tc.name: AppDataListenerWrap_OnBytesReceived_001 + * @tc.desc: test AppDataListenerWrap OnBytesReceived. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnBytesReceived_001, TestSize.Level1) +{ + PipeInfo pipeInfo = { "" }; + SoftBusAdapter softBusAdapter; + MockAppDataChangeListener observer; + auto ret = softBusAdapter.StartWatchDataChange(&observer, pipeInfo); + EXPECT_EQ(Status::SUCCESS, ret); + int sessionId = 1; + AppDataListenerWrap::SetDataHandler(&softBusAdapter); + std::string data = "OnBytesReceived"; + AppDataListenerWrap::OnBytesReceived(sessionId, reinterpret_cast(data.c_str()), data.size()); + EXPECT_EQ(data, observer.data); +} /** * @tc.name: DevManager_GetUuidByNodeId_001 diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp index 2a7ca405..28736d92 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_store_test.cpp @@ -18,20 +18,23 @@ #include #include +#include "accesstoken_kit.h" #include "auto_launch_export.h" -#include "flat_object_store.h" -#include "flat_object_storage_engine.h" #include "distributed_object.h" +#include "distributed_object_impl.h" #include "distributed_objectstore.h" #include "distributed_objectstore_impl.h" +#include "flat_object_storage_engine.h" +#include "flat_object_store.h" #include "hilog/log.h" +#include "ipc_skeleton.h" #include "kv_store_delegate_manager.h" +#include "mock_flat_object_watcher.h" +#include "mock_object_watcher.h" +#include "nativetoken_kit.h" #include "object_storage_engine.h" #include "objectstore_errors.h" #include "store_observer.h" -#include "ipc_skeleton.h" -#include "accesstoken_kit.h" -#include "nativetoken_kit.h" #include "token_setproc.h" using namespace testing::ext; @@ -191,6 +194,150 @@ HWTEST_F(NativeObjectStoreTest, DistributedObjectStore_Create_Destroy_004, TestS EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: DistributedObjectStoreImpl_CreateObject_001 + * @tc.desc: test Create DistributedObjectStoreImpl + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_CreateObject_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + + DistributedObject *object = objectStore->CreateObject(""); + EXPECT_EQ(nullptr, object); +} + +/** + * @tc.name: DistributedObjectStoreImpl_CreateObject_002 + * @tc.desc: test Create DistributedObjectStoreImpl + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_CreateObject_002, TestSize.Level1) +{ + std::string sessionId = "123456"; + auto objectStore = DistributedObjectStoreImpl(nullptr); + uint32_t status = -1; + DistributedObject *object = objectStore.CreateObject(sessionId, status); + EXPECT_EQ(nullptr, object); + EXPECT_EQ(ERR_NULL_OBJECTSTORE, status); + + status = objectStore.DeleteObject(sessionId); + EXPECT_EQ(ERR_NULL_OBJECTSTORE, status); +} + +/** + * @tc.name: DistributedObjectStoreImpl_CreateObject_003 + * @tc.desc: test Create DistributedObjectStoreImpl + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_CreateObject_003, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = ""; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + + uint32_t status = -1; + DistributedObject *object = objectStore->CreateObject(sessionId, status); + EXPECT_EQ(nullptr, object); + EXPECT_EQ(ERR_INVALID_ARGS, status); + + status = objectStore->DeleteObject(sessionId); + EXPECT_EQ(ERR_DB_NOT_EXIST, status); +} + +/** + * @tc.name: DistributedObjectStoreImpl_Get_001 + * @tc.desc: test DistributedObjectStoreImpl Get + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_Get_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "sessionId"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + DistributedObject *Object1 = nullptr; + uint32_t status = objectStore->Get("", &Object1); + EXPECT_EQ(ERR_GET_OBJECT, status); + + status = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, status); +} + +/** + * @tc.name: DistributedObjectStoreImpl_Watch_001 + * @tc.desc: test DistributedObjectStoreImpl Watch + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_Watch_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "sessionId"; + auto objectStore = new DistributedObjectStoreImpl(nullptr); + + std::shared_ptr watcher = std::make_shared(); + uint32_t status = objectStore->Watch(nullptr, watcher); + EXPECT_EQ(ERR_NULL_OBJECT, status); + + auto flatObjectStore = new FlatObjectStore(bundleName); + auto object = new DistributedObjectImpl(sessionId, flatObjectStore); + + status = objectStore->Watch(object, watcher); + EXPECT_EQ(ERR_NULL_OBJECTSTORE, status); + + status = objectStore->UnWatch(object); + EXPECT_EQ(ERR_NULL_OBJECTSTORE, status); + delete objectStore; + delete flatObjectStore; + delete object; +} + +/** + * @tc.name: DistributedObjectStoreImpl_Watch_002 + * @tc.desc: test DistributedObjectStoreImpl Watch + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObjectStoreImpl_Watch_002, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "sessionId"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + std::shared_ptr watcher = std::make_shared(); + uint32_t status = objectStore->Watch(object, watcher); + EXPECT_EQ(SUCCESS, status); + + status = objectStore->Watch(object, watcher); + EXPECT_EQ(ERR_EXIST, status); + + std::string bundleName1 = "default1"; + std::string sessionId1 = "sessionId1"; + auto flatObjectStore = new FlatObjectStore(bundleName1); + auto object1 = new DistributedObjectImpl(sessionId1, flatObjectStore); + status = objectStore->Watch(object1, watcher); + EXPECT_EQ(ERR_DB_NOT_EXIST, status); + + status = objectStore->UnWatch(object1); + EXPECT_EQ(ERR_DB_NOT_EXIST, status); + + status = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, status); + delete flatObjectStore; + delete object1; +} + /** * @tc.name: DistributedObjectStore_Get_001 * @tc.desc: test DistributedObjectStore Get. @@ -259,6 +406,7 @@ HWTEST_F(NativeObjectStoreTest, DistributedObjectStore_SetStatusNotifier_001, Te uint32_t ret = objectStore->SetStatusNotifier(notifierPtr); EXPECT_EQ(ret, 0); + objectStore->NotifyCachedStatus(sessionId); ret = objectStore->DeleteObject(sessionId); EXPECT_EQ(ret, 0); } @@ -289,6 +437,29 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Double_001, TestSize.Level1) EXPECT_EQ(ret, 0); } +/** + * @tc.name: DistributedObject_GetDouble_001 + * @tc.desc: test DistributedObjectStore GetDouble. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetDouble_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + double value = 0.0; + uint32_t ret = object->GetDouble("salary", value); + EXPECT_EQ(ret, DistributedDB::DBStatus::NOT_FOUND); + EXPECT_EQ(value, 0.0); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(ret, 0); +} + /** * @tc.name: DistributedObject_Boolean_001 * @tc.desc: test DistributedObjectStore PutBoolean. @@ -315,6 +486,29 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Boolean_001, TestSize.Level1) EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: DistributedObject_GetBoolean_001 + * @tc.desc: test DistributedObjectStore GetBoolean. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetBoolean_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + bool value = false; + uint32_t ret = object->GetBoolean("isTrue", value); + EXPECT_EQ(DistributedDB::DBStatus::NOT_FOUND, ret); + EXPECT_EQ(false, value); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + /** * @tc.name: DistributedObject_String_001 * @tc.desc: test DistributedObjectStore String. @@ -341,6 +535,29 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_String_001, TestSize.Level1) EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: DistributedObject_GetString_001 + * @tc.desc: test DistributedObjectStore GetString. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetString_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + std::string value = ""; + uint32_t ret = object->GetString("name", value); + EXPECT_EQ(DistributedDB::DBStatus::NOT_FOUND, ret); + EXPECT_EQ(value, ""); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + /** * @tc.name: DistributedObject_GetSessionId_001 * @tc.desc: test DistributedObjectStore GetSessionId. @@ -360,6 +577,71 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_GetSessionId_001, TestSize.Lev EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: DistributedObject_PutComplex_001 + * @tc.desc: test DistributedObjectStore PutComplex. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_PutComplex_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + std::vector value = {'z', 'h'}; + uint32_t ret = object->PutComplex("name", value); + EXPECT_EQ(SUCCESS, ret); + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: DistributedObject_GetComplex_001 + * @tc.desc: test DistributedObjectStore GetComplex. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetComplex_001, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + std::vector value = {'z', 'h'}; + uint32_t ret = object->PutComplex("name", value); + EXPECT_EQ(SUCCESS, ret); + ret = object->GetComplex("name", value); + EXPECT_EQ(SUCCESS, ret); + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: DistributedObject_GetComplex_002 + * @tc.desc: test DistributedObjectStore GetComplex. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetComplex_002, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + std::vector value = {'z', 'h'}; + uint32_t ret = object->GetComplex("name", value); + EXPECT_EQ(DistributedDB::DBStatus::NOT_FOUND, ret); + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + /** * @tc.name: DistributedObject_TestSetSessionId_001 * @tc.desc: test DistributedObjectStore TestSetSessionId. @@ -421,6 +703,29 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_GetType_001, TestSize.Level1) EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: DistributedObject_GetType_002 + * @tc.desc: test DistributedObject GetType. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_GetType_002, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + Type type; + uint32_t ret = object->GetType("name", type); + EXPECT_EQ(DistributedDB::DBStatus::NOT_FOUND, ret); + EXPECT_EQ(TYPE_STRING, type); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + /** * @tc.name: DistributedObject_Save_RevokeSave_001 * @tc.desc: test DistributedObjectStore Save. @@ -435,6 +740,7 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_001, TestSize. DistributedObject *object = objectStore->CreateObject(sessionId); EXPECT_NE(nullptr, object); + uint32_t ret = object->PutString("name", "zhangsan"); EXPECT_EQ(SUCCESS, ret); ret = object->PutDouble("salary", SALARY); @@ -487,6 +793,27 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_002, TestSize. t3.join(); } +/** + * @tc.name: DistributedObject_Save_RevokeSave_003 + * @tc.desc: test DistributedObjectStore Save. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, DistributedObject_Save_RevokeSave_003, TestSize.Level1) +{ + std::string bundleName = "default"; + std::string sessionId = "123456"; + DistributedObjectStore *objectStore = DistributedObjectStore::GetInstance(bundleName); + EXPECT_NE(nullptr, objectStore); + DistributedObject *object = objectStore->CreateObject(sessionId); + EXPECT_NE(nullptr, object); + + uint32_t ret = object->RevokeSave(); + EXPECT_EQ(SUCCESS, ret); + + ret = objectStore->DeleteObject(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + /** * @tc.name: DistributedObject_Open_001 * @tc.desc: test ObjectStorageEngine Open, calling Open repeatedly. @@ -695,10 +1022,10 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_UpdateItems_001, TestSize.Leve /** * @tc.name: FlatObjectStore_UpdateItems_002 - * @tc.desc: test FlatObjectStore FilterData. + * @tc.desc: test FlatObjectStore UpdateItems. * @tc.type: FUNC */ -HWTEST_F(NativeObjectStoreTest, DistributedObject_UpdateItems_002, TestSize.Level1) +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_UpdateItems_002, TestSize.Level1) { std::string bundleName = "default07"; std::string sessionId = "session07"; @@ -753,11 +1080,11 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_NotifyChange_001, TestSize.Lev } /** - * @tc.name: DistributedObject_CheckRetrieveCache_001 + * @tc.name: FlatObjectStore_CheckRetrieveCache_001 * @tc.desc: test FlatObjectStore CheckRetrieveCache. * @tc.type: FUNC */ -HWTEST_F(NativeObjectStoreTest, DistributedObject_CheckRetrieveCache_001, TestSize.Level1) +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_CheckRetrieveCache_001, TestSize.Level1) { std::string sessionId = "session05"; std::string bundleName = "default07"; @@ -770,11 +1097,11 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_CheckRetrieveCache_001, TestSi } /** - * @tc.name: DistributedObject_SyncAllData_001 + * @tc.name: FlatObjectStore_SyncAllData_001 * @tc.desc: test FlatObjectStore SyncAllData. * @tc.type: FUNC */ -HWTEST_F(NativeObjectStoreTest, DistributedObject_SyncAllData_001, TestSize.Level1) +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_SyncAllData_001, TestSize.Level1) { std::string sessionId = "session258"; std::string bundleName = "default07"; @@ -788,13 +1115,196 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_SyncAllData_001, TestSize.Leve } }; ret = flatObjectStore->SyncAllData(sessionId, onComplete); - EXPECT_EQ(ERR_SINGLE_DEVICE, ret); + EXPECT_EQ(SUCCESS, ret); ret = flatObjectStore->SyncAllData("", onComplete); EXPECT_EQ(ERR_DB_NOT_EXIST, ret); ret = flatObjectStore->Delete(sessionId); EXPECT_EQ(SUCCESS, ret); } +/** + * @tc.name: FlatObjectStore_Delete_001 + * @tc.desc: test FlatObjectStore Delete. wrong sessionId + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_Delete_001, TestSize.Level1) +{ + std::string sessionId = "session001"; + std::string bundleName = "default001"; + std::shared_ptr flatObjectStore = std::make_shared(bundleName); + uint32_t ret = flatObjectStore->CreateObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + sessionId = "session002"; + ret = flatObjectStore->Delete(sessionId); + EXPECT_EQ(ERR_DB_NOT_EXIST, ret); +} + +/** + * @tc.name: FlatObjectStore_Delete_002 + * @tc.desc: test FlatObjectStore Delete. wrong sessionId + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_Delete_002, TestSize.Level1) +{ + std::string sessionId = "session001"; + std::string bundleName = ""; + std::shared_ptr flatObjectStore = std::make_shared(bundleName); + uint32_t ret = flatObjectStore->CreateObject(sessionId); + EXPECT_EQ(ERR_DB_GETKV_FAIL, ret); +} + +/** + * @tc.name: FlatObjectStore_Watch_001 + * @tc.desc: test FlatObjectStore Watch. wrong sessionId + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_Watch_001, TestSize.Level1) +{ + std::string sessionId = "session002"; + std::string bundleName = "default002"; + std::shared_ptr flatObjectStore = std::make_shared(bundleName); + uint32_t ret = flatObjectStore->CreateObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + sessionId = "session003"; + std::shared_ptr watcher = std::make_shared(sessionId); + ret = flatObjectStore->Watch(sessionId, watcher); + EXPECT_EQ(ERR_DB_NOT_EXIST, ret); +} + +/** + * @tc.name: FlatObjectStore_UnWatch_001 + * @tc.desc: test FlatObjectStore UnWatch. wrong sessionId + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_UnWatch_001, TestSize.Level1) +{ + std::string sessionId = "session003"; + std::string bundleName = "default003"; + std::shared_ptr flatObjectStore = std::make_shared(bundleName); + uint32_t ret = flatObjectStore->CreateObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + sessionId = "session004"; + std::shared_ptr watcher = std::make_shared(sessionId); + ret = flatObjectStore->UnWatch(sessionId); + EXPECT_EQ(ERR_DB_NOT_EXIST, ret); +} + +/** + * @tc.name: FlatObjectStore_Save_001 + * @tc.desc: test FlatObjectStore Save. wrong sessionId + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_Save_001, TestSize.Level1) +{ + std::string sessionId = "session004"; + std::string bundleName = "default004"; + std::string deviceId = "deviceId004"; + std::shared_ptr flatObjectStore = std::make_shared(bundleName); + uint32_t ret = flatObjectStore->CreateObject(sessionId); + EXPECT_EQ(SUCCESS, ret); + sessionId = "session005"; + std::shared_ptr watcher = std::make_shared(sessionId); + ret = flatObjectStore->Save(sessionId, deviceId); + EXPECT_EQ(ERR_DB_NOT_EXIST, ret); +} + +/** + * @tc.name: FlatObjectStore_OnComplete_001 + * @tc.desc: test FlatObjectStore OnComplete. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, FlatObjectStore_OnComplete_001, TestSize.Level1) +{ + std::string bundleName = "default005"; + std::string sessionId = "session005"; + std::shared_ptr storageEngine = std::make_shared(); + uint32_t ret = storageEngine->Open(bundleName); + EXPECT_EQ(SUCCESS, ret); + ret = storageEngine->CreateTable(sessionId); + std::shared_ptr statusWatcher = std::make_shared(); + DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; + std::map devices = { { sessionId, status } }; + storageEngine->OnComplete(sessionId, devices, statusWatcher); + ret = storageEngine->DeleteTable(sessionId); + EXPECT_EQ(SUCCESS, ret); +} + +/** + * @tc.name: CacheManager_Save_001 + * @tc.desc: test CacheManager Save. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_Save_001, TestSize.Level1) +{ + std::string bundleName = ""; + std::string sessionId = ""; + std::string deviceId = ""; + std::map> objectData; + CacheManager cacheManager; + auto ret = cacheManager.Save(bundleName, sessionId, deviceId, objectData); + EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); +} + +/** + * @tc.name: CacheManager_RevokeSave_001 + * @tc.desc: test CacheManager RevokeSave. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_RevokeSave_001, TestSize.Level1) +{ + std::string bundleName = ""; + std::string sessionId = ""; + CacheManager cacheManager; + auto ret = cacheManager.RevokeSave(bundleName, sessionId); + EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); +} + +/** + * @tc.name: CacheManager_ResumeObject_001 + * @tc.desc: test CacheManager ResumeObject. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_ResumeObject_001, TestSize.Level1) +{ + std::string bundleName = ""; + std::string sessionId = ""; + CacheManager cacheManager; + std::function> &data)> callback = + [](const std::map> &data) {}; + auto ret = cacheManager.ResumeObject(bundleName, sessionId, callback); + EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); +} + +/** + * @tc.name: CacheManager_SubscribeDataChange_001 + * @tc.desc: test CacheManager SubscribeDataChange. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_SubscribeDataChange_001, TestSize.Level1) +{ + std::string bundleName = ""; + std::string sessionId = ""; + CacheManager cacheManager; + std::function> &data)> callback = + [](const std::map> &data) {}; + auto ret = cacheManager.SubscribeDataChange(bundleName, sessionId, callback); + EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); +} + +/** + * @tc.name: CacheManager_UnregisterDataChange_001 + * @tc.desc: test CacheManager UnregisterDataChange. + * @tc.type: FUNC + */ +HWTEST_F(NativeObjectStoreTest, CacheManager_UnregisterDataChange_001, TestSize.Level1) +{ + std::string bundleName = ""; + std::string sessionId = ""; + CacheManager cacheManager; + auto ret = cacheManager.UnregisterDataChange(bundleName, sessionId); + EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); +} + /** * @tc.name: DistributedObject_NotifyCachedStatus_001 * @tc.desc: test DistributedObjectStore NotifyCachedStatus. @@ -834,27 +1344,6 @@ HWTEST_F(NativeObjectStoreTest, DistributedObject_UnWatch_001, TestSize.Level1) EXPECT_EQ(SUCCESS, ret); } -/** - * @tc.name: DistributedObject_OnComplete_001 - * @tc.desc: test FlatObjectStore OnComplete. - * @tc.type: FUNC - */ -HWTEST_F(NativeObjectStoreTest, DistributedObject_OnComplete_001, TestSize.Level1) -{ - std::string bundleName = "default"; - std::string sessionId = "123456"; - std::shared_ptr storageEngine = std::make_shared(); - uint32_t ret = storageEngine->Open(bundleName); - EXPECT_EQ(SUCCESS, ret); - ret = storageEngine->CreateTable(sessionId); - std::shared_ptr statusWatcher = std::make_shared(); - DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; - std::map devices = { { sessionId, status } }; - storageEngine->OnComplete(sessionId, devices, statusWatcher); - ret = storageEngine->DeleteTable(sessionId); - EXPECT_EQ(SUCCESS, ret); -} - /** * @tc.name: DistributedObject_CreateTable_004 * @tc.desc: test FlatObjectStorageEngine CreateTable, sessionId is empty. diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/process_communicator_impl_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/process_communicator_impl_test.cpp index dd1c69f4..65456ae1 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/process_communicator_impl_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/process_communicator_impl_test.cpp @@ -74,6 +74,21 @@ HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_Start_Stop_0 delete processCommunicator; } +/** + * @tc.name: ProcessCommunicatorImpl_Start_Stop_002 + * @tc.desc: test ProcessCommunicatorImpl Start and Stop. + * @tc.type: FUNC + */ +HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_Start_Stop_002, TestSize.Level1) +{ + std::string processLabel = "processLabel"; + ProcessCommunicatorImpl processCommunicator; + auto ret = processCommunicator.Start(processLabel); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); + ret = processCommunicator.Stop(); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); +} + /** * @tc.name: ProcessCommunicatorImpl_RegOnDeviceChange_001 * @tc.desc: test ProcessCommunicatorImpl RegOnDeviceChange. @@ -157,10 +172,17 @@ HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_RegOnDataRec */ HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_RegOnDataReceive_002, TestSize.Level1) { - ProcessCommunicatorImpl *processCommunicator = new ProcessCommunicatorImpl(); - auto ret = processCommunicator->RegOnDataReceive(nullptr); - EXPECT_EQ(DistributedDB::DBStatus::DB_ERROR, ret); - delete processCommunicator; + std::string processLabel = "processLabel"; + ProcessCommunicatorImpl processCommunicator; + auto ret = processCommunicator.Start(processLabel); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); + + ret = processCommunicator.RegOnDataReceive( + [](const DistributedDB::DeviceInfos &srcDevInfo, const uint8_t *data, uint32_t length) -> void { return; }); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); + + ret = processCommunicator.RegOnDataReceive(nullptr); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); } /** @@ -180,6 +202,25 @@ HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_SendData_001 delete processCommunicator; } +/** + * @tc.name: ProcessCommunicatorImpl_SendData_002 + * @tc.desc: test ProcessCommunicatorImpl SendData. + * @tc.type: FUNC + */ +HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_SendData_002, TestSize.Level1) +{ + std::string processLabel = "processLabel02"; + ProcessCommunicatorImpl processCommunicator; + auto ret = processCommunicator.Start(processLabel); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); + + DistributedDB::DeviceInfos deviceInfos = { "identifier" }; + uint8_t data = 1; + uint32_t length = 1; + ret = processCommunicator.SendData(deviceInfos, &data, length); + EXPECT_EQ(DistributedDB::DBStatus::OK, ret); +} + /** * @tc.name: ProcessCommunicatorImpl_GetMtuSize_001 * @tc.desc: test ProcessCommunicatorImpl GetMtuSize. @@ -196,6 +237,22 @@ HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_GetMtuSize_0 delete processCommunicator; } +/** + * @tc.name: ProcessCommunicatorImpl_GetMtuSize_002 + * @tc.desc: test ProcessCommunicatorImpl GetMtuSize. + * @tc.type: FUNC + */ +HWTEST_F(NativeProcessCommunicatorImplTest, ProcessCommunicatorImpl_GetMtuSize_002, TestSize.Level1) +{ + ProcessCommunicatorImpl *processCommunicator = new ProcessCommunicatorImpl(); + DistributedDB::DeviceInfos deviceInfos = { "" }; + auto ret = processCommunicator->GetMtuSize(deviceInfos); + EXPECT_EQ(MTU_SIZE, ret); + ret = processCommunicator->GetMtuSize(); + EXPECT_EQ(MTU_SIZE, ret); + delete processCommunicator; +} + /** * @tc.name: ProcessCommunicatorImpl_IsSameProcessLabelStartedOnPeerDevice_001 * @tc.desc: test ProcessCommunicatorImpl IsSameProcessLabelStartedOnPeerDevice. 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 3d9697df..ffb68c40 100644 --- a/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h +++ b/data_object/frameworks/jskitsimpl/include/adaptor/js_object_wrapper.h @@ -40,7 +40,7 @@ public: private: DistributedObjectStore *objectStore_; DistributedObject *object_; - std::unique_ptr watcher_ = nullptr; + std::shared_ptr watcher_ = nullptr; std::shared_mutex watchMutex_{}; std::vector undefinedProperties; std::string objectId_; diff --git a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h index 699186aa..6316d436 100644 --- a/data_object/frameworks/jskitsimpl/include/common/uv_queue.h +++ b/data_object/frameworks/jskitsimpl/include/common/uv_queue.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "napi/native_api.h" @@ -25,7 +26,7 @@ namespace OHOS::ObjectStore { typedef void (*Process)(napi_env env, std::list &); -class UvQueue { +class UvQueue : public std::enable_shared_from_this { public: UvQueue(napi_env env); virtual ~UvQueue(); @@ -33,6 +34,10 @@ public: void CallFunction(Process process, void *argv); private: + struct UvEntry { + std::weak_ptr uvQueue_; + }; + napi_env env_; std::shared_mutex mutex_{}; // key is callback,value is list of args 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 5c211f69..4df37cb2 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_object_wrapper.cpp @@ -41,7 +41,7 @@ bool JSObjectWrapper::AddWatch(napi_env env, const char *type, napi_value handle { std::unique_lock cacheLock(watchMutex_); if (watcher_ == nullptr) { - watcher_ = std::make_unique(env, objectStore_, object_); + watcher_ = std::make_shared(env, objectStore_, object_); if (watcher_ == nullptr) { LOG_ERROR("JSObjectWrapper::new JSWatcher fail"); return false; diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp index 9e1895d0..901436b6 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp @@ -140,9 +140,9 @@ void JSWatcher::ProcessStatus(napi_env env, std::list &args) ASSERT_MATCH_ELSE_GOTO_ERROR(status == napi_ok); status = JSUtil::SetValue(env, statusArgs->sessionId_, param[0]); ASSERT_MATCH_ELSE_GOTO_ERROR(status == napi_ok); - JSUtil::SetValue(env, statusArgs->networkId_, param[1]); + status = JSUtil::SetValue(env, statusArgs->networkId_, param[1]); ASSERT_MATCH_ELSE_GOTO_ERROR(status == napi_ok); - JSUtil::SetValue(env, statusArgs->status_, param[2]); + status = JSUtil::SetValue(env, statusArgs->status_, param[2]); ASSERT_MATCH_ELSE_GOTO_ERROR(status == napi_ok); LOG_INFO("start %{public}s, %{public}s, %{public}s", statusArgs->sessionId_.c_str(), statusArgs->networkId_.c_str(), statusArgs->status_.c_str()); diff --git a/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp b/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp index bf30994e..5f3ef204 100644 --- a/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp +++ b/data_object/frameworks/jskitsimpl/src/common/uv_queue.cpp @@ -38,7 +38,11 @@ void UvQueue::CallFunction(Process process, void *argv) LOG_ERROR("no memory for uv_work_t"); return; } - work->data = this; + work->data = new (std::nothrow)UvEntry { weak_from_this() }; + if (work->data == nullptr) { + LOG_ERROR("no memory for UvEntry"); + return; + } { std::unique_lock cacheLock(mutex_); if (args_.count(process) != 0) { @@ -52,20 +56,33 @@ void UvQueue::CallFunction(Process process, void *argv) } } - uv_queue_work( + int ret = uv_queue_work( loop_, work, [](uv_work_t *work) {}, [](uv_work_t *work, int uvstatus) { - auto queue = static_cast(work->data); - { + UvEntry *entry = static_cast(work->data); + auto queue = entry->uvQueue_.lock(); + if (queue != nullptr) { std::unique_lock cacheLock(queue->mutex_); for (auto &item : queue->args_) { item.first(queue->env_, item.second); } queue->args_.clear(); } - + delete entry; + entry = nullptr; delete work; work = nullptr; }); + if (ret != 0) { + if (work->data != nullptr) { + UvEntry *uvEntry = static_cast(work->data); + delete uvEntry; + uvEntry = nullptr; + } + if (work != nullptr) { + delete work; + work = nullptr; + } + } } } // namespace OHOS::ObjectStore diff --git a/data_object/frameworks/jskitsimpl/test/unittest/src/config.json b/data_object/frameworks/jskitsimpl/test/unittest/src/config.json index 20d7f293..7ab092a1 100644 --- a/data_object/frameworks/jskitsimpl/test/unittest/src/config.json +++ b/data_object/frameworks/jskitsimpl/test/unittest/src/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/data_object/interfaces/innerkits/BUILD.gn b/data_object/interfaces/innerkits/BUILD.gn index fbe4aeb7..0702c9c0 100644 --- a/data_object/interfaces/innerkits/BUILD.gn +++ b/data_object/interfaces/innerkits/BUILD.gn @@ -55,7 +55,6 @@ object_source_config = [ "../../frameworks/innerkitsimpl/src/object_service_proxy.cpp", ] object_deps_config = [ - "${kvstore_path}/libs/distributeddb:distributeddb", "//third_party/bounds_checking_function:libsec_shared", "//third_party/libuv:uv", ] @@ -68,6 +67,7 @@ object_external_deps_config = [ "hilog:libhilog", "ipc:ipc_core", "kv_store:distributeddata_inner", + "kv_store:distributeddb", "samgr:samgr_proxy", ] ohos_shared_library("distributeddataobject_impl") { diff --git a/data_object/interfaces/jskits/BUILD.gn b/data_object/interfaces/jskits/BUILD.gn index b2b70587..623f885b 100644 --- a/data_object/interfaces/jskits/BUILD.gn +++ b/data_object/interfaces/jskits/BUILD.gn @@ -43,9 +43,6 @@ config("objectstore_config") { "../../frameworks/innerkitsimpl/include/communicator", "../../interfaces/innerkits", "${kvstore_path}/common", - "${kvstore_path}/libs/distributeddb/interfaces/include", - "${kvstore_path}/libs/distributeddb/interfaces/include/relational", - "${kvstore_path}/libs/distributeddb/include", ] } @@ -107,6 +104,7 @@ ohos_shared_library("distributeddataobject") { "access_token:libaccesstoken_sdk", "common_event_service:cesfwk_innerkits", "hilog:libhilog", + "kv_store:distributeddb", "napi:ace_napi", ] diff --git a/data_object/samples/distributedNotepad/entry/src/main/config.json b/data_object/samples/distributedNotepad/entry/src/main/config.json index fb3676f5..7bff9d0c 100644 --- a/data_object/samples/distributedNotepad/entry/src/main/config.json +++ b/data_object/samples/distributedNotepad/entry/src/main/config.json @@ -15,6 +15,7 @@ "srcPath": "", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/data_share/bundle.json b/data_share/bundle.json index 1f23b4c2..4ffb7437 100644 --- a/data_share/bundle.json +++ b/data_share/bundle.json @@ -60,11 +60,9 @@ "hilog", "ipc", "ipc_js", - "libuv", "napi", "relational_store", - "samgr", - "utils_base" + "samgr" ], "third_party": [ "libuv" diff --git a/data_share/frameworks/native/common/include/callbacks_manager.h b/data_share/frameworks/native/common/include/callbacks_manager.h index 7dd33229..4152f78d 100644 --- a/data_share/frameworks/native/common/include/callbacks_manager.h +++ b/data_share/frameworks/native/common/include/callbacks_manager.h @@ -26,6 +26,13 @@ namespace OHOS::DataShare { template class CallbacksManager { public: + struct ObserverNodeOnEnabled { + ObserverNodeOnEnabled(const std::shared_ptr &observer, bool isNotifyOnEnabled = false) + : observer_(observer), isNotifyOnEnabled_(isNotifyOnEnabled) {}; + std::shared_ptr observer_; + bool isNotifyOnEnabled_; + }; + std::vector AddObservers(const std::vector &keys, void *subscriber, const std::shared_ptr observer, std::function &, const std::shared_ptr &observer)>, @@ -41,7 +48,7 @@ public: CallbacksManager::DefaultProcess); std::vector EnableObservers(const std::vector &keys, void *subscriber, - std::function>> &)> processOnLocalEnabled, + std::function> &)> processOnLocalEnabled, std::function &, std::vector &)>); std::vector DisableObservers(const std::vector &keys, void *subscriber, @@ -54,16 +61,20 @@ public: int GetEnabledSubscriberSize(const Key &key); void RecoverObservers(std::function &)> recoverObservers); + void SetObserversNotifiedOnEnabled(const Key &key); + private: static void DefaultProcess(const std::vector &, std::vector &){}; struct ObserverNode { std::shared_ptr observer_; bool enabled_; void *subscriber_; + bool isNotifyOnEnabled_; ObserverNode(const std::shared_ptr &observer, void *subscriber) : observer_(observer), subscriber_(subscriber) { enabled_ = true; + isNotifyOnEnabled_ = false; }; }; void DelLocalObservers(const Key &key, void *subscriber, std::vector &lastDelKeys, @@ -216,12 +227,12 @@ std::vector> CallbacksManager::GetEnabl template std::vector CallbacksManager::EnableObservers( const std::vector &keys, void *subscriber, - std::function>> &)> processOnLocalEnabled, + std::function> &)> processOnLocalEnabled, std::function &, std::vector &)> processOnFirstEnabled) { std::vector result; std::vector firstRegisterKey; - std::map>> localEnabledObservers; + std::map> localEnabledObservers; { std::lock_guard lck(mutex_); for (auto &key : keys) { @@ -233,11 +244,15 @@ std::vector CallbacksManager::EnableObservers( std::vector> enabledObservers = GetEnabledObservers(key); bool hasEnabled = false; for (auto &item : callbacks_[key]) { - if (item.subscriber_ == subscriber) { - localEnabledObservers[key].emplace_back(item.observer_); - item.enabled_ = true; - hasEnabled = true; + if (item.subscriber_ != subscriber) { + continue; } + hasEnabled = true; + if (item.enabled_) { + continue; + } + localEnabledObservers[key].emplace_back(item.observer_, item.isNotifyOnEnabled_); + item.enabled_ = true; } if (!hasEnabled) { result.emplace_back(key, E_SUBSCRIBER_NOT_EXIST); @@ -252,7 +267,7 @@ std::vector CallbacksManager::EnableObservers( } } if (!localEnabledObservers.empty()) { - processOnLocalEnabled(localEnabledObservers); + processOnLocalEnabled(localEnabledObservers); } processOnFirstEnabled(firstRegisterKey, result); return result; @@ -283,6 +298,7 @@ std::vector CallbacksManager::DisableObservers(c for (auto &item : callbacks_[key]) { if (item.subscriber_ == subscriber) { item.enabled_ = false; + item.isNotifyOnEnabled_ = false; hasDisabled = true; } } @@ -330,5 +346,21 @@ int CallbacksManager::GetEnabledSubscriberSize(const Key &key) } return count; } + +template +void CallbacksManager::SetObserversNotifiedOnEnabled(const Key &key) +{ + std::lock_guard lck(mutex_); + auto it = callbacks_.find(key); + if (it == callbacks_.end()) { + return; + } + std::vector &callbacks = it->second; + for (auto &observerNode : callbacks) { + if (!observerNode.enabled_) { + observerNode.isNotifyOnEnabled_ = true; + } + } +} } // namespace OHOS::DataShare #endif // DATA_SHARE_CALLBACKS_MANAGER_H diff --git a/data_share/frameworks/native/common/include/datashare_itypes_utils.h b/data_share/frameworks/native/common/include/datashare_itypes_utils.h index 25e27ebc..3bbeb0f0 100644 --- a/data_share/frameworks/native/common/include/datashare_itypes_utils.h +++ b/data_share/frameworks/native/common/include/datashare_itypes_utils.h @@ -16,6 +16,7 @@ #ifndef DATASHARE_COMMON_ITYPES_UTIL_H #define DATASHARE_COMMON_ITYPES_UTIL_H +#include "datashare_operation_statement.h" #include "datashare_predicates.h" #include "datashare_template.h" #include "datashare_values_bucket.h" @@ -34,7 +35,9 @@ using PublishedDataChangeNode = DataShare::PublishedDataChangeNode; using OperationResult = DataShare::OperationResult; using DataShareValuesBucket = DataShare::DataShareValuesBucket; using AshmemNode = DataShare::AshmemNode; - +using OperationStatement = DataShare::OperationStatement; +using ExecResult = DataShare::ExecResult; +using ExecResultSet = DataShare::ExecResultSet; template<> bool Marshalling(const Predicates &bucket, MessageParcel &parcel); @@ -110,5 +113,23 @@ bool Unmarshalling(OperationResult &predicateTemplateNode, MessageParcel &parcel template<> bool Marshalling(const TemplateId &changeNode, MessageParcel &parcel); + +template<> +bool Marshalling(const OperationStatement &operationStatement, MessageParcel &parcel); + +template<> +bool Unmarshalling(OperationStatement &operationStatement, MessageParcel &parcel); + +template<> +bool Marshalling(const ExecResult &execResult, MessageParcel &parcel); + +template<> +bool Unmarshalling(ExecResult &execResult, MessageParcel &parcel); + +template<> +bool Marshalling(const ExecResultSet &execResultSet, MessageParcel &parcel); + +template<> +bool Unmarshalling(ExecResultSet &execResultSet, MessageParcel &parcel); } #endif 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 4000bafb..e992208e 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 @@ -36,6 +36,7 @@ enum class IDataShareInterfaceCode { CMD_NORMALIZE_URI, CMD_DENORMALIZE_URI, CMD_EXECUTE_BATCH, + CMD_INSERT_EXT, }; enum class ISharedResultInterfaceCode { @@ -91,7 +92,8 @@ enum class DataShareServiceInterfaceCode { }; enum class IKvStoreDataInterfaceCode { - GET_FEATURE_INTERFACE = 0 + GET_FEATURE_INTERFACE = 0, + REGISTERCLIENTDEATHOBSERVER }; } } // namespace OHOS diff --git a/data_share/frameworks/native/common/include/idatashare.h b/data_share/frameworks/native/common/include/idatashare.h index 11bd40f9..7a76650e 100644 --- a/data_share/frameworks/native/common/include/idatashare.h +++ b/data_share/frameworks/native/common/include/idatashare.h @@ -19,6 +19,7 @@ #include #include "datashare_business_error.h" +#include "datashare_operation_statement.h" #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_values_bucket.h" @@ -41,6 +42,8 @@ public: virtual int Insert(const Uri &uri, const DataShareValuesBucket &value) = 0; + virtual int InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) = 0; + virtual int Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) = 0; virtual int Delete(const Uri &uri, const DataSharePredicates &predicates) = 0; @@ -52,6 +55,8 @@ public: virtual int BatchInsert(const Uri &uri, const std::vector &values) = 0; + virtual int ExecuteBatch(const std::vector &statements, ExecResultSet &result) = 0; + virtual bool RegisterObserver(const Uri &uri, const sptr &dataObserver) = 0; virtual bool UnregisterObserver(const Uri &uri, const sptr &dataObserver) = 0; 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 4dcfc497..b18c292e 100644 --- a/data_share/frameworks/native/common/include/ikvstore_data_service.h +++ b/data_share/frameworks/native/common/include/ikvstore_data_service.h @@ -32,6 +32,8 @@ public: virtual sptr GetFeatureInterface(const std::string &name) = 0; + virtual uint32_t RegisterClientDeathObserver(const std::string &appId, sptr observer) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.IKvStoreDataService"); }; @@ -40,6 +42,7 @@ public: explicit DataShareKvServiceProxy(const sptr &impl); ~DataShareKvServiceProxy() = default; sptr GetFeatureInterface(const std::string &name) override; + uint32_t RegisterClientDeathObserver(const std::string &appId, sptr observer) override; }; } } diff --git a/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp b/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp index 8021a298..80a32474 100644 --- a/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp +++ b/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp @@ -185,4 +185,58 @@ bool Unmarshalling(DataShareValuesBucket &bucket, MessageParcel &parcel) { return ITypesUtil::Unmarshal(parcel, bucket.valuesMap); } + +template<> +bool Marshalling(const OperationStatement &operationStatement, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, static_cast(operationStatement.operationType), + operationStatement.uri, operationStatement.valuesBucket, operationStatement.predicates); +} + +template<> +bool Unmarshalling(OperationStatement &operationStatement, MessageParcel &parcel) +{ + int type; + if (!ITypesUtil::Unmarshalling(type, parcel)) { + return false; + } + operationStatement.operationType = static_cast(type); + return ITypesUtil::Unmarshal(parcel, operationStatement.uri, + operationStatement.valuesBucket, operationStatement.predicates); +} + +template<> +bool Marshalling(const ExecResult &execResult, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, static_cast(execResult.operationType), execResult.code, + execResult.message); +} + +template<> +bool Unmarshalling(ExecResult &execResult, MessageParcel &parcel) +{ + int type; + if (!ITypesUtil::Unmarshalling(type, parcel)) { + return false; + } + execResult.operationType = static_cast(type); + return ITypesUtil::Unmarshal(parcel, execResult.code, execResult.message); +} + +template<> +bool Marshalling(const ExecResultSet &execResultSet, MessageParcel &parcel) +{ + return ITypesUtil::Marshal(parcel, static_cast(execResultSet.errorCode), execResultSet.results); +} + +template<> +bool Unmarshalling(ExecResultSet &execResultSet, MessageParcel &parcel) +{ + int errorCode; + if (!ITypesUtil::Unmarshalling(errorCode, parcel)) { + return false; + } + execResultSet.errorCode = static_cast(errorCode); + return ITypesUtil::Unmarshal(parcel, execResultSet.results); +} } // namespace OHOS::ITypesUtil diff --git a/data_share/frameworks/native/common/src/ikvstore_data_service.cpp b/data_share/frameworks/native/common/src/ikvstore_data_service.cpp index 29f746ce..89f4672a 100644 --- a/data_share/frameworks/native/common/src/ikvstore_data_service.cpp +++ b/data_share/frameworks/native/common/src/ikvstore_data_service.cpp @@ -14,6 +14,7 @@ */ #include "ikvstore_data_service.h" +#include "datashare_itypes_utils.h" #include "datashare_log.h" using namespace OHOS::DistributedShare::DataShare; @@ -54,5 +55,32 @@ sptr DataShareKvServiceProxy::GetFeatureInterface(const std::stri } return remoteObject; } + +uint32_t DataShareKvServiceProxy::RegisterClientDeathObserver(const std::string &appId, sptr observer) +{ + if (observer == nullptr) { + LOG_ERROR("observer is nullptr"); + return -1; + } + + MessageParcel data; + MessageParcel reply; + if (!data.WriteInterfaceToken(DataShareKvServiceProxy::GetDescriptor())) { + LOG_ERROR("write descriptor failed"); + return -1; + } + if (!ITypesUtil::Marshal(data, appId, observer)) { + LOG_ERROR("remote observer fail"); + return -1; + } + MessageOption mo { MessageOption::TF_SYNC }; + int32_t error = Remote()->SendRequest( + static_cast(IKvStoreDataInterfaceCode::REGISTERCLIENTDEATHOBSERVER), data, reply, mo); + if (error != 0) { + LOG_WARN("failed during IPC. errCode %{public}d", error); + return -1; + } + return static_cast(reply.ReadInt32()); +} } } diff --git a/data_share/frameworks/native/common/src/ishared_result_set_stub.cpp b/data_share/frameworks/native/common/src/ishared_result_set_stub.cpp index 6fd0020b..0b9874ad 100644 --- a/data_share/frameworks/native/common/src/ishared_result_set_stub.cpp +++ b/data_share/frameworks/native/common/src/ishared_result_set_stub.cpp @@ -34,7 +34,7 @@ sptr ISharedResultSetStub::CreateStub(std::shared_ptrAsObject().GetRefPtr()); + parcel.WriteRemoteObject(stub->AsObject()); result->Marshalling(parcel); return stub; } diff --git a/data_share/frameworks/native/consumer/controller/provider/include/ext_special_controller.h b/data_share/frameworks/native/consumer/controller/provider/include/ext_special_controller.h index 4c3d7a69..586cf908 100644 --- a/data_share/frameworks/native/consumer/controller/provider/include/ext_special_controller.h +++ b/data_share/frameworks/native/consumer/controller/provider/include/ext_special_controller.h @@ -17,6 +17,7 @@ #define EXT_SPECIAL_CONTROLLER_H #include "datashare_connection.h" +#include "datashare_operation_statement.h" #include "datashare_values_bucket.h" #include "uri.h" @@ -35,6 +36,10 @@ public: std::string GetType(const Uri &uri); int BatchInsert(const Uri &uri, const std::vector &values); + + int ExecuteBatch(const std::vector &statements, ExecResultSet &result); + + int InsertExt(Uri &uri, const DataShareValuesBucket &value, std::string &result); Uri NormalizeUri(const Uri &uri); diff --git a/data_share/frameworks/native/consumer/controller/provider/src/ext_special_controller.cpp b/data_share/frameworks/native/consumer/controller/provider/src/ext_special_controller.cpp index 3da33f95..d3843704 100644 --- a/data_share/frameworks/native/consumer/controller/provider/src/ext_special_controller.cpp +++ b/data_share/frameworks/native/consumer/controller/provider/src/ext_special_controller.cpp @@ -79,6 +79,36 @@ int ExtSpecialController::BatchInsert(const Uri &uri, const std::vectorBatchInsert(uri, values); } +int ExtSpecialController::InsertExt(Uri &uri, const DataShareValuesBucket &value, std::string &result) +{ + auto connection = connection_; + if (connection == nullptr) { + LOG_ERROR("connection is nullptr"); + return INVALID_VALUE; + } + auto proxy = connection->GetDataShareProxy(uri_, token_); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return INVALID_VALUE; + } + return proxy->InsertExt(uri, value, result); +} + +int ExtSpecialController::ExecuteBatch(const std::vector &statements, ExecResultSet &result) +{ + auto connection = connection_; + if (connection == nullptr) { + LOG_ERROR("connection is nullptr"); + return INVALID_VALUE; + } + auto proxy = connection->GetDataShareProxy(uri_, token_); + if (proxy == nullptr) { + LOG_ERROR("proxy is nullptr"); + return INVALID_VALUE; + } + return proxy->ExecuteBatch(statements, result); +} + Uri ExtSpecialController::NormalizeUri(const Uri &uri) { auto connection = connection_; 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 24cf3930..c2027292 100644 --- a/data_share/frameworks/native/consumer/include/datashare_helper_impl.h +++ b/data_share/frameworks/native/consumer/include/datashare_helper_impl.h @@ -41,6 +41,8 @@ public: int Insert(Uri &uri, const DataShareValuesBucket &value) override; + int InsertExt(Uri &uri, const DataShareValuesBucket &value, std::string &result) override; + int Update(Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; int Delete(Uri &uri, const DataSharePredicates &predicates) override; @@ -52,6 +54,8 @@ public: int BatchInsert(Uri &uri, const std::vector &values) override; + int ExecuteBatch(const std::vector &statements, ExecResultSet &result) override; + void RegisterObserver(const Uri &uri, const sptr &dataObserver) override; void UnregisterObserver(const Uri &uri, const sptr &dataObserver) override; diff --git a/data_share/frameworks/native/consumer/include/datashare_proxy.h b/data_share/frameworks/native/consumer/include/datashare_proxy.h index bf96e6c1..82c23341 100644 --- a/data_share/frameworks/native/consumer/include/datashare_proxy.h +++ b/data_share/frameworks/native/consumer/include/datashare_proxy.h @@ -37,6 +37,8 @@ public: virtual int Insert(const Uri &uri, const DataShareValuesBucket &value) override; + virtual int InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) override; + virtual int Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) override; @@ -49,6 +51,8 @@ public: virtual int BatchInsert(const Uri &uri, const std::vector &values) override; + virtual int ExecuteBatch(const std::vector &statements, ExecResultSet &result) override; + virtual bool RegisterObserver(const Uri &uri, const sptr &dataObserver) override; virtual bool UnregisterObserver(const Uri &uri, const sptr &dataObserver) override; diff --git a/data_share/frameworks/native/consumer/src/datashare_connection.cpp b/data_share/frameworks/native/consumer/src/datashare_connection.cpp index 6bfd9f3c..7ebc017f 100644 --- a/data_share/frameworks/native/consumer/src/datashare_connection.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_connection.cpp @@ -15,7 +15,7 @@ #include "datashare_connection.h" -#include "ability_manager_client.h" +#include "ams_mgr_proxy.h" #include "datashare_proxy.h" #include "datashare_log.h" @@ -76,14 +76,8 @@ std::shared_ptr DataShareConnection::ConnectDataShareExtAbility( if (dataShareProxy_ != nullptr) { return dataShareProxy_; } - - AAFwk::Want want; - if (uri_.ToString().empty()) { - want.SetUri(uri); - } else { - want.SetUri(uri_); - } - ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, token); + auto reqUri = uri_.ToString().empty() ? uri.ToString() : uri_.ToString(); + ErrCode ret = AmsMgrProxy::GetInstance()->Connect(reqUri, this, token); if (ret != ERR_OK) { LOG_ERROR("connect ability failed, ret = %{public}d", ret); return nullptr; @@ -105,7 +99,7 @@ void DataShareConnection::DisconnectDataShareExtAbility() if (dataShareProxy_ == nullptr) { return; } - ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this); + ErrCode ret = AmsMgrProxy::GetInstance()->DisConnect(this); if (ret != ERR_OK) { LOG_ERROR("disconnect ability failed, ret = %{public}d", ret); return; diff --git a/data_share/frameworks/native/consumer/src/datashare_helper.cpp b/data_share/frameworks/native/consumer/src/datashare_helper.cpp index 3017fc88..94523c0f 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper.cpp @@ -36,7 +36,7 @@ public: explicit ObserverImpl(const std::shared_ptr dataShareObserver) : dataShareObserver_(dataShareObserver){}; void OnChange(); - void OnChangeExt(const ChangeInfo &info); + void OnChangeExt(const AAFwk::ChangeInfo &info); static DataShareObserver::ChangeInfo ConvertInfo(const AAFwk::ChangeInfo &info); static AAFwk::ChangeInfo ConvertInfo(const DataShareObserver::ChangeInfo &info); static sptr GetObserver(const Uri& uri, const std::shared_ptr &observer); @@ -62,27 +62,6 @@ std::string DataShareHelper::TransferUriPrefix(const std::string &originPrefix, return replacedPrefix + originUriStr.substr(originPrefix.length()); } -/** - * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship - * between the ability using the Data template (data share for short) and the associated client process in - * a DataShareHelper instance. - * - * @param context Indicates the Context object on OHOS. - * @param strUri Indicates the database table or disk file to operate. - * - * @return Returns the created DataShareHelper instance. - */ -std::shared_ptr DataShareHelper::Creator(const std::shared_ptr &context, - const std::string &strUri) -{ - if (context == nullptr) { - LOG_ERROR("DataShareHelper::Creator failed, context == nullptr"); - return nullptr; - } - sptr token = context->GetToken(); - return Creator(token, strUri); -} - /** * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship * between the ability using the Data template (data share for short) and the associated client process in @@ -252,7 +231,7 @@ void DataShareHelper::NotifyChangeExt(const DataShareObserver::ChangeInfo &chang void ObserverImpl::OnChange() {} -void ObserverImpl::OnChangeExt(const ChangeInfo &info) +void ObserverImpl::OnChangeExt(const AAFwk::ChangeInfo &info) { dataShareObserver_->OnChange(ConvertInfo(info)); } 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 5f7a8696..71c7dc73 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp @@ -31,12 +31,14 @@ constexpr int INVALID_VALUE = -1; DataShareHelperImpl::DataShareHelperImpl(const Uri &uri, const sptr &token, std::shared_ptr connection) { + LOG_DEBUG("starts"); generalCtl_ = std::make_shared(connection, uri, token); extSpCtl_ = std::make_shared(connection, uri, token); } DataShareHelperImpl::DataShareHelperImpl() { + LOG_DEBUG("starts"); generalCtl_ = std::make_shared(); persistentDataCtl_ = std::make_shared(); publishedDataCtl_ = std::make_shared(); @@ -97,6 +99,16 @@ int DataShareHelperImpl::Insert(Uri &uri, const DataShareValuesBucket &value) return generalCtl->Insert(uri, value); } +int DataShareHelperImpl::InsertExt(Uri &uri, const DataShareValuesBucket &value, std::string &result) +{ + auto extSpCtl = extSpCtl_; + if (extSpCtl == nullptr) { + LOG_ERROR("providerSpCtl is nullptr"); + return INVALID_VALUE; + } + return extSpCtl->InsertExt(uri, value, result); +} + int DataShareHelperImpl::Update(Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) { auto generalCtl = generalCtl_; @@ -153,6 +165,16 @@ int DataShareHelperImpl::BatchInsert(Uri &uri, const std::vectorBatchInsert(uri, values); } +int DataShareHelperImpl::ExecuteBatch(const std::vector &statements, ExecResultSet &result) +{ + auto extSpCtl = extSpCtl_; + if (extSpCtl == nullptr) { + LOG_ERROR("extSpCtl is nullptr"); + return INVALID_VALUE; + } + return extSpCtl->ExecuteBatch(statements, result); +} + void DataShareHelperImpl::RegisterObserver(const Uri &uri, const sptr &dataObserver) { LOG_INFO("Start"); diff --git a/data_share/frameworks/native/consumer/src/datashare_proxy.cpp b/data_share/frameworks/native/consumer/src/datashare_proxy.cpp index b0819336..83eda8f5 100644 --- a/data_share/frameworks/native/consumer/src/datashare_proxy.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_proxy.cpp @@ -168,6 +168,33 @@ int DataShareProxy::Insert(const Uri &uri, const DataShareValuesBucket &value) return index; } +int DataShareProxy::InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) +{ + int index = -1; + MessageParcel data; + if (!data.WriteInterfaceToken(DataShareProxy::GetDescriptor())) { + LOG_ERROR("WriteInterfaceToken failed"); + return index; + } + if (!ITypesUtil::Marshal(data, uri, value)) { + LOG_ERROR("fail to Marshal value"); + return index; + } + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest( + static_cast(IDataShareInterfaceCode::CMD_INSERT_EXT), data, reply, option); + if (err != DATA_SHARE_NO_ERROR) { + LOG_ERROR("Insert fail to SendRequest. err: %{public}d", err); + return index; + } + if (!ITypesUtil::Unmarshal(reply, index, result)) { + LOG_ERROR("fail to Unmarshal index"); + return index; + } + return index; +} + int DataShareProxy::Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) { int index = -1; @@ -315,6 +342,33 @@ int DataShareProxy::BatchInsert(const Uri &uri, const std::vector &statements, ExecResultSet &result) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(DataShareProxy::GetDescriptor())) { + LOG_ERROR("WriteInterfaceToken failed"); + return -1; + } + if (!ITypesUtil::Marshal(data, statements)) { + LOG_ERROR("fail to Marshal"); + return -1; + } + + MessageParcel reply; + MessageOption option; + int32_t err = Remote()->SendRequest( + static_cast(IDataShareInterfaceCode::CMD_EXECUTE_BATCH), data, reply, option); + if (err != DATA_SHARE_NO_ERROR) { + LOG_ERROR("fail to SendRequest. err: %{public}d", err); + return -1; + } + if (!ITypesUtil::Unmarshal(reply, result)) { + LOG_ERROR("fail to Unmarshal result"); + return -1; + } + return 0; +} + bool DataShareProxy::RegisterObserver(const Uri &uri, const sptr &dataObserver) { LOG_INFO("begin."); diff --git a/data_share/frameworks/native/provider/include/datashare_ext_ability.h b/data_share/frameworks/native/provider/include/datashare_ext_ability.h index dcafee55..066d5133 100644 --- a/data_share/frameworks/native/provider/include/datashare_ext_ability.h +++ b/data_share/frameworks/native/provider/include/datashare_ext_ability.h @@ -22,6 +22,7 @@ #include "datashare_values_bucket.h" #include "datashare_predicates.h" #include "datashare_result_set.h" +#include "datashare_operation_statement.h" namespace OHOS { namespace AAFwk { @@ -111,6 +112,17 @@ public: */ virtual int Insert(const Uri &uri, const DataShareValuesBucket &value); + /** + * @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. + * @param result Indicates the data result to insert. + * + * @return Returns the index of the inserted data record. + */ + virtual int InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result); + /** * @brief Updates data records in the database. * @@ -166,6 +178,16 @@ public: */ virtual int BatchInsert(const Uri &uri, const std::vector &values); + /** + * @brief Performs batch operations on the database. + * + * @param statements Indicates a list of database operation statement on the database. + * @param result Indicates the result of the operation. + * + * @return Returns the ipc result. + */ + virtual int ExecuteBatch(const std::vector &statements, ExecResultSet &result); + /** * @brief Registers an observer to DataObsMgr specified by the given Uri. * diff --git a/data_share/frameworks/native/provider/include/datashare_stub.h b/data_share/frameworks/native/provider/include/datashare_stub.h index 02c0f15d..4e489ad4 100644 --- a/data_share/frameworks/native/provider/include/datashare_stub.h +++ b/data_share/frameworks/native/provider/include/datashare_stub.h @@ -45,6 +45,11 @@ private: ErrCode CmdNotifyChange(MessageParcel &data, MessageParcel &reply); ErrCode CmdNormalizeUri(MessageParcel &data, MessageParcel &reply); ErrCode CmdDenormalizeUri(MessageParcel &data, MessageParcel &reply); + ErrCode CmdExecuteBatch(MessageParcel &data, MessageParcel &reply); + ErrCode CmdInsertExt(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; using RequestFuncType = int (DataShareStub::*)(MessageParcel &data, MessageParcel &reply); std::map stubFuncMap_; diff --git a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp index 66e6faff..637d62db 100644 --- a/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp +++ b/data_share/frameworks/native/provider/src/datashare_ext_ability.cpp @@ -83,6 +83,11 @@ int DataShareExtAbility::Insert(const Uri &uri, const DataShareValuesBucket &val return -1; } +int DataShareExtAbility::InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) +{ + return -1; +} + int DataShareExtAbility::Update(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) { @@ -110,6 +115,11 @@ int DataShareExtAbility::BatchInsert(const Uri &uri, const std::vector &statements, ExecResultSet &result) +{ + return -1; +} + bool DataShareExtAbility::RegisterObserver(const Uri &uri, const sptr &dataObserver) { return true; diff --git a/data_share/frameworks/native/provider/src/datashare_stub.cpp b/data_share/frameworks/native/provider/src/datashare_stub.cpp index 019359dc..096c2e33 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub.cpp @@ -20,6 +20,7 @@ #include "datashare_log.h" #include "ipc_types.h" #include "ishared_result_set.h" +#include "datashare_operation_statement.h" #include "unistd.h" using namespace OHOS::DistributedShare::DataShare; @@ -47,6 +48,8 @@ DataShareStub::DataShareStub() stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_NORMALIZE_URI)] = &DataShareStub::CmdNormalizeUri; stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_DENORMALIZE_URI)] = &DataShareStub::CmdDenormalizeUri; + stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_EXECUTE_BATCH)] = &DataShareStub::CmdExecuteBatch; + stubFuncMap_[static_cast(IDataShareInterfaceCode::CMD_INSERT_EXT)] = &DataShareStub::CmdInsertExt; } DataShareStub::~DataShareStub() @@ -356,5 +359,56 @@ ErrCode DataShareStub::CmdDenormalizeUri(MessageParcel &data, MessageParcel &rep } return DATA_SHARE_NO_ERROR; } + +ErrCode DataShareStub::CmdExecuteBatch(MessageParcel &data, MessageParcel &reply) +{ + std::vector statements; + ExecResultSet result; + if (!ITypesUtil::Unmarshal(data, statements)) { + LOG_ERROR("Unmarshalling OperationStatement failed"); + return ERR_INVALID_VALUE; + } + auto ret = ExecuteBatch(statements, result); + if (ret == DEFAULT_NUMBER) { + LOG_ERROR("ExecuteBatch error"); + return ERR_INVALID_VALUE; + } + if (!ITypesUtil::Marshal(reply, result)) { + LOG_ERROR("fail to write result"); + return ERR_INVALID_VALUE; + } + return DATA_SHARE_NO_ERROR; +} + +ErrCode DataShareStub::CmdInsertExt(MessageParcel &data, MessageParcel &reply) +{ + Uri uri(""); + DataShareValuesBucket value; + if (!ITypesUtil::Unmarshal(data, uri, value)) { + LOG_ERROR("Unmarshalling value is nullptr"); + return ERR_INVALID_VALUE; + } + std::string result; + int index = InsertExt(uri, value, result); + if (index == DEFAULT_NUMBER) { + LOG_ERROR("Insert inner error"); + return ERR_INVALID_VALUE; + } + if (!ITypesUtil::Marshal(reply, index, result)) { + LOG_ERROR("fail to write result"); + return ERR_INVALID_VALUE; + } + return DATA_SHARE_NO_ERROR; +} + +int DataShareStub::ExecuteBatch(const std::vector &statements, ExecResultSet &result) +{ + return 0; +} + +int DataShareStub::InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) +{ + return 0; +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h b/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h new file mode 100644 index 00000000..429eb9f3 --- /dev/null +++ b/data_share/frameworks/native/proxy/include/ams_mgr_proxy.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_PROXY_AMS_PROXY_H +#define DATA_PROXY_AMS_PROXY_H + +#include +#include + +#include "extension_manager_proxy.h" +namespace OHOS::DataShare { +class AmsMgrProxy final : public std::enable_shared_from_this { +public: + ~AmsMgrProxy(); + static std::shared_ptr 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(std::weak_ptr owner) : owner_(owner) + { + } + void OnRemoteDied(const wptr &object) override + { + auto owner = owner_.lock(); + if (owner != nullptr) { + owner->OnProxyDied(); + } + } + + private: + std::weak_ptr owner_; + }; + void OnProxyDied(); + bool ConnectSA(); + std::mutex mutex_; + sptr sa_; + sptr proxy_; + sptr deathRecipient_; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H 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 6605e9c3..8848383c 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 @@ -22,6 +22,7 @@ #include "data_share_service_proxy.h" #include "data_share_errno.h" +#include "idata_share_client_death_observer.h" #include "iremote_object.h" #include "refbase.h" @@ -68,6 +69,8 @@ private: void ResetServiceHandle(); + void RegisterClientDeathObserver(); + static std::shared_ptr GetDistributedDataManager(); std::mutex mutex_; @@ -81,6 +84,7 @@ private: static constexpr int MIN_THREADS = 0; std::shared_ptr pool_; std::function)> deathCallback_ = {}; + sptr clientDeathObserverPtr_; }; } } // namespace OHOS::DataShare diff --git a/data_share/frameworks/native/proxy/include/idata_share_client_death_observer.h b/data_share/frameworks/native/proxy/include/idata_share_client_death_observer.h new file mode 100644 index 00000000..1980e09b --- /dev/null +++ b/data_share/frameworks/native/proxy/include/idata_share_client_death_observer.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_DATA_SHARE_CLIENT_DEATH_OBSERVER_H +#define I_DATA_SHARE_CLIENT_DEATH_OBSERVER_H + +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DataShare { +class IDataShareClientDeathObserver : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DataShare.IDataShareClientDeathObserver"); +}; + +class DataShareClientDeathObserverStub : public IRemoteStub { +public: + DataShareClientDeathObserverStub(); + + virtual ~DataShareClientDeathObserverStub(); +}; + +class DataShareClientDeathObserverProxy : public IRemoteProxy { +public: + explicit DataShareClientDeathObserverProxy(const sptr &impl) + : IRemoteProxy(impl){}; + ~DataShareClientDeathObserverProxy() = default; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DataShare +} // namespace OHOS + +#endif // I_DATA_SHARE_CLIENT_DEATH_OBSERVER_H diff --git a/data_share/frameworks/native/proxy/include/published_data_subscriber_manager.h b/data_share/frameworks/native/proxy/include/published_data_subscriber_manager.h index a5db17c4..8983837a 100644 --- a/data_share/frameworks/native/proxy/include/published_data_subscriber_manager.h +++ b/data_share/frameworks/native/proxy/include/published_data_subscriber_manager.h @@ -93,7 +93,7 @@ public: private: void Emit(const std::vector &keys, const std::shared_ptr &observer); - void Emit(std::map>> &obsMap); + void EmitOnEnable(std::map> &obsMap); PublishedDataSubscriberManager(); bool Init(); void Destroy(); diff --git a/data_share/frameworks/native/proxy/include/rdb_subscriber_manager.h b/data_share/frameworks/native/proxy/include/rdb_subscriber_manager.h index 45e296c5..46f28ac8 100644 --- a/data_share/frameworks/native/proxy/include/rdb_subscriber_manager.h +++ b/data_share/frameworks/native/proxy/include/rdb_subscriber_manager.h @@ -94,7 +94,7 @@ public: private: void Emit(const std::vector &keys, const std::shared_ptr &observer); - void Emit(std::map>> &obsMap); + void EmitOnEnable(std::map> &obsMap); RdbSubscriberManager(); bool Init(); void Destroy(); diff --git a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp new file mode 100644 index 00000000..3d6cb04b --- /dev/null +++ b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ams_mgr_proxy.h" + +#include "datashare_log.h" +#include "extension_ability_info.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "want.h" + +namespace OHOS::DataShare { +void AmsMgrProxy::OnProxyDied() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; + proxy_ = nullptr; +} + +AmsMgrProxy::~AmsMgrProxy() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } +} + +std::shared_ptr AmsMgrProxy::GetInstance() +{ + static std::shared_ptr proxy(new AmsMgrProxy()); + return proxy; +} + +int AmsMgrProxy::Connect( + const std::string &uri, const sptr &connect, const sptr &callerToken) +{ + AAFwk::Want want; + want.SetUri(uri); + std::lock_guard lock(mutex_); + if (ConnectSA()) { + int ret = proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); + if (ret != ERR_OK) { + LOG_ERROR("connect ability failed, ret = %{public}d", ret); + } + return ret; + } + return -1; +} + +bool AmsMgrProxy::ConnectSA() +{ + if (proxy_ != nullptr) { + return true; + } + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + LOG_ERROR("Failed to get system ability mgr."); + return false; + } + + sa_ = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (sa_ == nullptr) { + LOG_ERROR("Failed to GetSystemAbility."); + return false; + } + deathRecipient_ = new (std::nothrow) AmsMgrProxy::ServiceDeathRecipient(weak_from_this()); + if (deathRecipient_ == nullptr) { + LOG_ERROR("deathRecipient alloc failed."); + return false; + } + sa_->AddDeathRecipient(deathRecipient_); + proxy_ = new (std::nothrow)Proxy(sa_); + if (proxy_ == nullptr) { + LOG_ERROR("proxy_ null, new failed"); + return false; + } + return true; +} + +int AmsMgrProxy::DisConnect(sptr connect) +{ + std::lock_guard lock(mutex_); + if (ConnectSA()) { + int ret = proxy_->DisconnectAbility(connect); + if (ret != ERR_OK) { + LOG_ERROR("DisconnectAbility failed, ret = %{public}d", ret); + } + return ret; + } + return -1; +} +} // namespace OHOS::DataShare \ No newline at end of file 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 88110b64..7677f689 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 @@ -85,9 +85,26 @@ sptr DataShareManagerImpl::GetDataShareServiceProxy() LOG_ERROR("Get DataShare service failed!"); return nullptr; } + RegisterClientDeathObserver(); return iface_cast(remote); } +void DataShareManagerImpl::RegisterClientDeathObserver() +{ + if (dataMgrService_ == nullptr || bundleName_.empty()) { + return; + } + LOG_INFO("RegisterClientDeathObserver bundleName is %{public}s", bundleName_.c_str()); + if (clientDeathObserverPtr_ == nullptr) { + clientDeathObserverPtr_ = new (std::nothrow) DataShareClientDeathObserverStub(); + } + if (clientDeathObserverPtr_ == nullptr) { + LOG_WARN("new KvStoreClientDeathObserver failed"); + return; + } + dataMgrService_->RegisterClientDeathObserver(bundleName_, clientDeathObserverPtr_); +} + DataShareManagerImpl::DataShareManagerImpl() { LOG_INFO("construct"); diff --git a/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp b/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp new file mode 100644 index 00000000..d7f9651a --- /dev/null +++ b/data_share/frameworks/native/proxy/src/idata_share_client_death_observer.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "idata_share_client_death_observer.h" +#include "datashare_log.h" + +namespace OHOS { +namespace DataShare { +DataShareClientDeathObserverStub::DataShareClientDeathObserverStub() +{ + LOG_INFO("this client death observer"); +} + +DataShareClientDeathObserverStub::~DataShareClientDeathObserverStub() +{ + LOG_INFO("destructor this client death observer"); +} +} +} diff --git a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp index 01a49f2e..8536df3a 100644 --- a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp +++ b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp @@ -134,8 +134,8 @@ std::vector PublishedDataSubscriberManager::EnableObservers(voi keys.emplace_back(uri, subscriberId); }); return BaseCallbacks::EnableObservers( - keys, subscriber, [this](std::map>> &obsMap) { - Emit(obsMap); + keys, subscriber, [this](std::map> &obsMap) { + EmitOnEnable(obsMap); }, [&proxy, &subscriberId, subscriber, this](const std::vector &firstAddKeys, std::vector &opResult) { @@ -230,6 +230,7 @@ void PublishedDataSubscriberManager::Emit(PublishedDataChangeNode &changeNode) for (auto const &obs : callbacks) { results[obs].datas_.emplace_back(data.key_, data.subscriberId_, data.GetData()); } + BaseCallbacks::SetObserversNotifiedOnEnabled(key); } for (auto &[callback, node] : results) { node.ownerBundleName_ = changeNode.ownerBundleName_; @@ -253,7 +254,7 @@ void PublishedDataSubscriberManager::Emit(const std::vector &keys, const st observer->OnChange(node); } -void PublishedDataSubscriberManager::Emit(std::map>> &obsMap) +void PublishedDataSubscriberManager::EmitOnEnable(std::map> &obsMap) { std::map, PublishedDataChangeNode> results; for (auto &[key, obsVector] : obsMap) { @@ -264,8 +265,10 @@ void PublishedDataSubscriberManager::Emit(std::mapsecond.datas_) { PublishedObserverMapKey mapKey(data.key_, data.subscriberId_); for (auto &obs : obsVector) { - results[obs].datas_.emplace_back(data.key_, data.subscriberId_, data.GetData()); - results[obs].ownerBundleName_ = it->second.ownerBundleName_; + if (obs.isNotifyOnEnabled_) { + results[obs.observer_].datas_.emplace_back(data.key_, data.subscriberId_, data.GetData()); + results[obs.observer_].ownerBundleName_ = it->second.ownerBundleName_; + } } } } diff --git a/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp b/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp index 88692dc0..1feffaee 100644 --- a/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp +++ b/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp @@ -141,8 +141,8 @@ std::vector RdbSubscriberManager::EnableObservers(void *subscri keys.emplace_back(uri, templateId); }); return BaseCallbacks::EnableObservers(keys, subscriber, - [this](std::map>> &obsMap) { - Emit(obsMap); + [this](std::map> &obsMap) { + EmitOnEnable(obsMap); }, [&proxy, subscriber, &templateId, this](const std::vector &firstAddKeys, std::vector &opResult) { @@ -227,6 +227,7 @@ void RdbSubscriberManager::Emit(const RdbChangeNode &changeNode) obs->OnChange(changeNode); } } + BaseCallbacks::SetObserversNotifiedOnEnabled(key); } void RdbSubscriberManager::Emit(const std::vector &keys, const std::shared_ptr &observer) @@ -239,7 +240,7 @@ void RdbSubscriberManager::Emit(const std::vector &keys, const std::shared_ } } -void RdbSubscriberManager::Emit(std::map>> &obsMap) +void RdbSubscriberManager::EmitOnEnable(std::map> &obsMap) { for (auto &[key, obsVector] : obsMap) { auto it = lastChangeNodeMap_.find(key); @@ -247,7 +248,9 @@ void RdbSubscriberManager::Emit(std::mapOnChange(it->second); + if (obs.isNotifyOnEnabled_) { + obs.observer_->OnChange(it->second); + } } } } diff --git a/data_share/interfaces/inner_api/BUILD.gn b/data_share/interfaces/inner_api/BUILD.gn index 5ac401be..60772513 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_native_consumer_path}/include", "${datashare_native_provider_path}/include", "${datashare_native_proxy_path}/include", + "${ability_runtime_inner_api_path}/dataobs_manager/include", ] } @@ -65,9 +66,11 @@ ohos_shared_library("datashare_consumer") { "${datashare_native_consumer_path}/src/datashare_helper.cpp", "${datashare_native_consumer_path}/src/datashare_helper_impl.cpp", "${datashare_native_consumer_path}/src/datashare_proxy.cpp", + "${datashare_native_proxy_path}/src/ams_mgr_proxy.cpp", "${datashare_native_proxy_path}/src/data_proxy_observer_stub.cpp", "${datashare_native_proxy_path}/src/data_share_manager_impl.cpp", "${datashare_native_proxy_path}/src/data_share_service_proxy.cpp", + "${datashare_native_proxy_path}/src/idata_share_client_death_observer.cpp", "${datashare_native_proxy_path}/src/published_data_subscriber_manager.cpp", "${datashare_native_proxy_path}/src/rdb_subscriber_manager.cpp", ] @@ -81,9 +84,9 @@ ohos_shared_library("datashare_consumer") { "ability_base:want", "ability_base:zuri", "ability_runtime:ability_context_native", - "ability_runtime:ability_manager", "ability_runtime:app_context", "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", "c_utils:utils", "common_event_service:cesfwk_innerkits", "hilog:libhilog", @@ -155,6 +158,7 @@ ohos_shared_library("datashare_ext_ability_module") { "c_utils:utils", "common_event_service:cesfwk_innerkits", "hilog:libhilog", + "napi:ace_napi", ] relative_install_dir = "extensionability/" diff --git a/data_share/interfaces/inner_api/common/include/datashare_operation_statement.h b/data_share/interfaces/inner_api/common/include/datashare_operation_statement.h new file mode 100644 index 00000000..40c8332b --- /dev/null +++ b/data_share/interfaces/inner_api/common/include/datashare_operation_statement.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARE_OPERATION_STATEMENT_H +#define DATASHARE_OPERATION_STATEMENT_H + +#include "datashare_predicates.h" +#include "datashare_values_bucket.h" + +namespace OHOS { +namespace DataShare { +enum Operation : int32_t { + INSERT = 0, + UPDATE, + DELETE, +}; + +struct OperationStatement { + Operation operationType; + std::string uri; + DataSharePredicates predicates; + DataShareValuesBucket valuesBucket; +}; + +enum ExecErrorCode : int32_t { + EXEC_SUCCESS = 0, + EXEC_FAILED, + EXEC_PARTIAL_SUCCESS, +}; + +struct ExecResult { + Operation operationType; + int code; + std::string message; +}; + +struct ExecResultSet { + ExecErrorCode errorCode; + std::vector results; +}; +} +} +#endif // DATASHARE_OPERATION_STATEMENT_H diff --git a/data_share/interfaces/inner_api/common/include/datashare_template.h b/data_share/interfaces/inner_api/common/include/datashare_template.h index 2e2643c3..2488ede1 100644 --- a/data_share/interfaces/inner_api/common/include/datashare_template.h +++ b/data_share/interfaces/inner_api/common/include/datashare_template.h @@ -105,8 +105,7 @@ struct PublishedDataItem { PublishedDataItem(const PublishedDataItem &) = delete; PublishedDataItem &operator=(const PublishedDataItem &) = delete; virtual ~PublishedDataItem(); - PublishedDataItem(const std::string &key, - int64_t subscriberId, DataType value); + PublishedDataItem(const std::string &key, int64_t subscriberId, DataType value); PublishedDataItem(PublishedDataItem &&item); PublishedDataItem &operator=(PublishedDataItem &&item); bool IsAshmem() const; 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 babb0d7d..27b006c2 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_helper.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_helper.h @@ -16,14 +16,15 @@ #ifndef DATASHARE_HELPER_H #define DATASHARE_HELPER_H +#include #include #include #include -#include #include -#include "app/context.h" +#include "data_ability_observer_interface.h" #include "datashare_business_error.h" +#include "datashare_operation_statement.h" #include "datashare_predicates.h" #include "datashare_result_set.h" #include "datashare_template.h" @@ -69,17 +70,6 @@ public: */ virtual ~DataShareHelper() = default; - /** - * @brief Creates a DataShareHelper instance with the Uri specified based on the given Context. - * - * @param context Indicates the Context object on OHOS. - * @param strUri Indicates the database table or disk file to operate. - * - * @return Returns the created DataShareHelper instance with a specified Uri. - */ - static std::shared_ptr Creator(const std::shared_ptr &context, - const std::string &strUri); - /** * @brief You can use this method to specify the Uri of the data to operate and set the binding relationship * between the ability using the Data template (data share for short) and the associated client process in @@ -158,6 +148,17 @@ public: */ virtual int Insert(Uri &uri, const DataShareValuesBucket &value) = 0; + /** + * @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. + * @param result Indicates the result string of the insert operation. + * + * @return Returns the index of the inserted data record. + */ + virtual int InsertExt(Uri &uri, const DataShareValuesBucket &value, std::string &result) = 0; + /** * @brief Updates data records in the database. * @@ -212,6 +213,16 @@ public: */ virtual int BatchInsert(Uri &uri, const std::vector &values) = 0; + /** + * @brief Performs batch operations on the database. + * + * @param statements Indicates a list of database operation statement on the database. + * @param result Indicates the result of the operation. + * + * @return Returns the ipc result. + */ + virtual int ExecuteBatch(const std::vector &statements, ExecResultSet &result) = 0; + /** * @brief Registers an observer to DataObsMgr specified by the given Uri. * diff --git a/data_share/test/native/BUILD.gn b/data_share/test/native/BUILD.gn index 00e5a302..5ff2afac 100644 --- a/data_share/test/native/BUILD.gn +++ b/data_share/test/native/BUILD.gn @@ -143,7 +143,7 @@ ohos_unittest("ErrorCodeTest") { "access_token:libtoken_setproc", "c_utils:utils", "common_event_service:cesfwk_innerkits", - "hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -179,7 +179,7 @@ ohos_unittest("JoinTest") { "access_token:libtoken_setproc", "c_utils:utils", "common_event_service:cesfwk_innerkits", - "hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -215,7 +215,7 @@ ohos_unittest("ProxyDatasTest") { "access_token:libnativetoken", "access_token:libtoken_setproc", "c_utils:utils", - "hilog_native:libhilog", + "hilog:libhilog", "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", 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 b9303037..42b9acfb 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 @@ -34,6 +34,7 @@ std::shared_ptr dataShareHelper; std::string TBL_NAME0 = "name0"; std::string TBL_NAME1 = "name1"; constexpr int SUBSCRIBER_ID = 100; +std::atomic_int g_callbackTimes = 0; class ProxyDatasTest : public testing::Test { public: @@ -84,6 +85,7 @@ void ProxyDatasTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); + dataShareHelper = nullptr; } void ProxyDatasTest::SetUp(void) @@ -111,7 +113,7 @@ HWTEST_F(ProxyDatasTest, ProxyDatasTest_Insert_Test_001, TestSize.Level0) HWTEST_F(ProxyDatasTest, ProxyDatasTest_QUERY_Test_001, TestSize.Level0) { - LOG_INFO("ErrorCodeTest_QUERY_Test_001::Start"); + LOG_INFO("ProxyDatasTest_QUERY_Test_001::Start"); auto helper = dataShareHelper; Uri uri(DATA_SHARE_PROXY_URI); DataShare::DataSharePredicates predicates; @@ -122,7 +124,7 @@ HWTEST_F(ProxyDatasTest, ProxyDatasTest_QUERY_Test_001, TestSize.Level0) int result = 0; resultSet->GetRowCount(result); EXPECT_EQ(result, 1); - LOG_INFO("ErrorCodeTest_QUERY_Test_001::End"); + LOG_INFO("ProxyDatasTest_QUERY_Test_001::End"); } HWTEST_F(ProxyDatasTest, ProxyDatasTest_Template_Test_001, TestSize.Level0) @@ -209,84 +211,56 @@ HWTEST_F(ProxyDatasTest, ProxyDatasTest_Publish_Test_002, TestSize.Level0) LOG_INFO("ProxyDatasTest_Publish_Test_002::End"); } -HWTEST_F(ProxyDatasTest, ProxyDatasTest_SubscribeRdbData_Test_001, TestSize.Level0) +HWTEST_F(ProxyDatasTest, ProxyDatasTest_CombinationRdbData_Test_001, TestSize.Level0) { - LOG_INFO("ProxyDatasTest_SubscribeRdbData_Test_001::Start"); auto helper = dataShareHelper; - PredicateTemplateNode node1("p1", "select name0 as name from TBL00"); - PredicateTemplateNode node2("p2", "select name1 as name from TBL00"); + PredicateTemplateNode node("p1", "select name0 as name from TBL00"); std::vector nodes; - nodes.emplace_back(node1); - nodes.emplace_back(node2); + nodes.emplace_back(node); Template tpl(nodes, "select name1 as name from TBL00"); auto result = helper->AddQueryTemplate(DATA_SHARE_PROXY_URI, SUBSCRIBER_ID, tpl); EXPECT_EQ(result, 0); - std::vector uris; uris.emplace_back(DATA_SHARE_PROXY_URI); TemplateId tplId; tplId.subscriberId_ = SUBSCRIBER_ID; tplId.bundleName_ = "ohos.datashareproxyclienttest.demo"; - std::vector results = + std::vector results1 = helper->SubscribeRdbData(uris, tplId, [&tplId](const RdbChangeNode &changeNode) { EXPECT_EQ(changeNode.uri_, DATA_SHARE_PROXY_URI); EXPECT_EQ(changeNode.templateId_.bundleName_, tplId.bundleName_); EXPECT_EQ(changeNode.templateId_.subscriberId_, tplId.subscriberId_); + g_callbackTimes++; }); - EXPECT_EQ(results.size(), uris.size()); - for (auto const &operationResult : results) { + EXPECT_EQ(results1.size(), uris.size()); + for (auto const &operationResult : results1) { EXPECT_EQ(operationResult.errCode_, 0); } - LOG_INFO("ProxyDatasTest_SubscribeRdbData_Test_001::End"); -} - -HWTEST_F(ProxyDatasTest, ProxyDatasTest_DisableRdbSubs_Test_001, TestSize.Level0) -{ - LOG_INFO("ProxyDatasTest_DisableRdbSubs_Test_001::Start"); - auto helper = dataShareHelper; - std::vector uris; - uris.emplace_back(DATA_SHARE_PROXY_URI); - TemplateId tplId; - tplId.subscriberId_ = SUBSCRIBER_ID; - tplId.bundleName_ = "ohos.datashareproxyclienttest.demo"; - std::vector results = helper->DisableRdbSubs(uris, tplId); - for (auto const &operationResult : results) { + std::vector results2 = helper->DisableRdbSubs(uris, tplId); + for (auto const &operationResult : results2) { EXPECT_EQ(operationResult.errCode_, 0); } - LOG_INFO("ProxyDatasTest_DisableRdbSubs_Test_001::End"); -} - -HWTEST_F(ProxyDatasTest, ProxyDatasTest_EnableRdbSubs_Test_001, TestSize.Level0) -{ - LOG_INFO("ProxyDatasTest_EnableRdbSubs_Test_001::Start"); - auto helper = dataShareHelper; - std::vector uris; - uris.emplace_back(DATA_SHARE_PROXY_URI); - TemplateId tplId; - tplId.subscriberId_ = SUBSCRIBER_ID; - tplId.bundleName_ = "ohos.datashareproxyclienttest.demo"; - std::vector results = helper->EnableRdbSubs(uris, tplId); - for (auto const &operationResult : results) { + std::vector results3 = helper->EnableRdbSubs(uris, tplId); + for (auto const &operationResult : results3) { EXPECT_EQ(operationResult.errCode_, 0); } - LOG_INFO("ProxyDatasTest_EnableRdbSubs_Test_001::End"); -} - -HWTEST_F(ProxyDatasTest, ProxyDatasTest_UnsubscribeRdbData_Test_001, TestSize.Level0) -{ - LOG_INFO("ProxyDatasTest_UnSubscribeRdbData_Test_001::Start"); - auto helper = dataShareHelper; - std::vector uris; - uris.emplace_back(DATA_SHARE_PROXY_URI); - TemplateId tplId; - tplId.subscriberId_ = SUBSCRIBER_ID; - tplId.bundleName_ = "ohos.datashareproxyclienttest.demo"; - std::vector results = helper->UnsubscribeRdbData(uris, tplId); - EXPECT_EQ(results.size(), uris.size()); - for (auto const &operationResult : results) { + Uri uri(DATA_SHARE_PROXY_URI); + DataShare::DataShareValuesBucket valuesBucket1, valuesBucket2; + std::string name1 = "wu"; + std::string name2 = "liu"; + valuesBucket1.Put(TBL_NAME1, name1); + int retVal1 = helper->Insert(uri, valuesBucket1); + EXPECT_EQ((retVal1 > 0), true); + EXPECT_EQ(g_callbackTimes, 2); + std::vector results4 = helper->UnsubscribeRdbData(uris, tplId); + EXPECT_EQ(results4.size(), uris.size()); + for (auto const &operationResult : results4) { EXPECT_EQ(operationResult.errCode_, 0); } - LOG_INFO("ProxyDatasTest_UnSubscribeRdbData_Test_001::End"); + valuesBucket2.Put(TBL_NAME1, name2); + int retVal2 = helper->Insert(uri, valuesBucket2); + EXPECT_EQ((retVal2 > 0), true); + EXPECT_EQ(g_callbackTimes, 2); } HWTEST_F(ProxyDatasTest, ProxyDatasTest_SubscribePublishedData_Test_001, TestSize.Level0) diff --git a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp index 88ab9284..a5402f36 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp @@ -112,6 +112,8 @@ void ErrorCodeTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); + g_slientAccessHelper = nullptr; + dataShareHelper = nullptr; } void ErrorCodeTest::SetUp(void) {} diff --git a/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp index 1f83ca7c..20015ea1 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/join_test.cpp @@ -114,6 +114,7 @@ void JoinTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); + g_slientAccessHelper = nullptr; } void JoinTest::SetUp(void) {} 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 ff33dd80..6e25720d 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 @@ -12,19 +12,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "mediadatashare_unit_test.h" + #include #include -#include "mediadatashare_unit_test.h" +#include "abs_shared_result_set.h" #include "accesstoken_kit.h" #include "dataobs_mgr_changeinfo.h" #include "datashare_log.h" #include "hap_token_info.h" #include "iservice_registry.h" +#include "rdb_data_ability_utils.h" #include "system_ability_definition.h" #include "token_setproc.h" -#include "rdb_data_ability_utils.h" -#include "abs_shared_result_set.h" namespace OHOS { namespace DataShare { @@ -44,7 +45,7 @@ public: isSet_ = true; cv_.notify_one(); } - + T Wait() { std::unique_lock lock(mutex_); @@ -53,7 +54,7 @@ public: cv_.notify_one(); return data; } - + void Clear() { std::lock_guard lock(mutex_); @@ -73,13 +74,13 @@ class DataShareObserverTest : public DataShare::DataShareObserver { public: DataShareObserverTest() {} ~DataShareObserverTest() {} - + void OnChange(const ChangeInfo &changeInfo) override { changeInfo_ = changeInfo; data.Notify(changeInfo); } - + void Clear() { changeInfo_.changeType_ = INVAILD; @@ -88,7 +89,7 @@ public: changeInfo_.size_ = 0; data.Clear(); } - + ChangeInfo changeInfo_; ConditionLock data; }; @@ -97,6 +98,7 @@ constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; std::string DATA_SHARE_URI = "datashare:///com.acts.datasharetest"; std::string MEDIALIBRARY_DATA_URI = "datashare:///com.acts.datasharetest"; std::string MEDIALIBRARY_DATA_URI_ERROR = "test:///com.acts.datasharetest"; +std::string FILE_DATA_URI = "file://com.acts.datasharetest"; std::string NORMALIZE_URI = "normalize+datashare:///com.acts.datasharetest"; std::string DENORMALIZE_URI = "denormalize+datashare:///com.acts.datasharetest"; std::shared_ptr g_dataShareHelper; @@ -142,19 +144,19 @@ bool MediaDataShareUnitTest::ChangeInfoEqual(const ChangeInfo &changeInfo, const if (changeInfo.changeType_ != expectChangeInfo.changeType_) { return false; } - + if (!UrisEqual(changeInfo.uris_, expectChangeInfo.uris_)) { return false; } - + if (changeInfo.size_ != expectChangeInfo.size_) { return false; } - + if (changeInfo.data_ == nullptr && expectChangeInfo.data_ == nullptr) { return true; } - + return memcmp(changeInfo.data_, expectChangeInfo.data_, expectChangeInfo.size_) == 0; } @@ -166,7 +168,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) ASSERT_TRUE(g_dataShareHelper != nullptr); int sleepTime = 1; sleep(sleepTime); - + Uri uri(MEDIALIBRARY_DATA_URI); DataShare::DataShareValuesBucket valuesBucket; double valueD1 = 20.07; @@ -176,7 +178,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) valuesBucket.Put("age", value1); int retVal = g_dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); - + valuesBucket.Clear(); double valueD2 = 20.08; valuesBucket.Put("phoneNumber", valueD2); @@ -185,7 +187,7 @@ void MediaDataShareUnitTest::SetUpTestCase(void) valuesBucket.Put("age", value2); retVal = g_dataShareHelper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); - + valuesBucket.Clear(); double valueD3 = 20.09; valuesBucket.Put("phoneNumber", valueD3); @@ -208,7 +210,7 @@ void MediaDataShareUnitTest::TearDownTestCase(void) int retVal = helper->Delete(deleteAssetUri, predicates); LOG_INFO("TearDownTestCase Delete retVal: %{public}d", retVal); EXPECT_EQ((retVal >= 0), true); - + bool result = helper->Release(); EXPECT_EQ(result, true); LOG_INFO("TearDownTestCase end"); @@ -567,7 +569,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_021, TestSize.Le LOG_INFO("MediaDataShare_Predicates_Test_021::Start"); DataShare::DataSharePredicates predicates; predicates.EqualTo("name", "dataShareTest003"); - + std::vector operationItems = predicates.GetOperationList(); DataShare::OperationItem operationItem = operationItems[0]; EXPECT_EQ(operationItem.operation, DataShare::OperationType::EQUAL_TO); @@ -595,7 +597,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Predicates_Test_023, TestSize.Le { LOG_INFO("MediaDataShare_Predicates_Test_024::Start"); DataShare::DataSharePredicates predicates; - int res = predicates.SetWhereArgs(std::vector { "-5" }); + int res = predicates.SetWhereArgs(std::vector{ "-5" }); EXPECT_EQ(res, 0); vector args = predicates.GetWhereArgs(); EXPECT_EQ(args[0], "-5"); @@ -862,7 +864,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_003, TestSize.Lev auto resultSet = helper->Query(uri, predicates, columns); AppDataFwk::SharedBlock *block = nullptr; ASSERT_TRUE(resultSet != nullptr); - + bool hasBlock = resultSet->HasBlock(); EXPECT_EQ(hasBlock, true); block = resultSet->GetBlock(); @@ -957,15 +959,6 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ResultSet_Test_006, TestSize.Lev LOG_INFO("MediaDataShare_ResultSet_Test_006, End"); } -HWTEST_F(MediaDataShareUnitTest, Creator_ContextNull_Test_001, TestSize.Level0) -{ - LOG_INFO("Creator_ContextNull_Test_001::Start"); - std::shared_ptr remoteObjCon = nullptr; - auto remoteNull = DataShare::DataShareHelper::Creator(remoteObjCon, MEDIALIBRARY_DATA_URI); - EXPECT_EQ(remoteNull, nullptr); - LOG_INFO("Creator_ContextNull_Test_001 End"); -} - HWTEST_F(MediaDataShareUnitTest, Creator_IRemoteObjectNull_Test_001, TestSize.Level0) { LOG_INFO("Creator_IRemoteObjectNull_Test_001::Start"); @@ -1003,7 +996,7 @@ HWTEST_F(MediaDataShareUnitTest, Insert_ConnectionNull_Test_001, TestSize.Level0 valuesBucket.Put("name", "dataShareTest006"); int value4 = 998; valuesBucket.Put("age", value4); - auto resultInsert= helper->Insert(uri, valuesBucket); + auto resultInsert = helper->Insert(uri, valuesBucket); EXPECT_EQ(resultInsert, -1); auto resultGetType = helper->GetType(uri); @@ -1056,7 +1049,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_NotImplPredicates_Test_001, Test inColumn.push_back("dataShare_Test_001"); inColumn.push_back("dataShare_Test_002"); predicates.In("name", inColumn); - + vector notInColumn; notInColumn.push_back("dataShare_Test_003"); notInColumn.push_back("dataShare_Test_004"); @@ -1084,7 +1077,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_Observer_001, TestSize.Level0) Uri uri(MEDIALIBRARY_DATA_URI); sptr dataObserver; helper->RegisterObserver(uri, dataObserver); - + DataShare::DataShareValuesBucket valuesBucket; valuesBucket.Put("name", "Datashare_Observer_Test001"); int retVal = helper->Insert(uri, valuesBucket); @@ -1134,7 +1127,7 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ObserverExt_001, TestSize.Level0 retVal = helper->Delete(uri, deletePredicates); EXPECT_EQ((retVal >= 0), true); char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; - ChangeInfo delChanges = { DataShareObserver::ChangeType::DELETE, { uri }, data, sizeof(data)/sizeof(data[0]) } ; + ChangeInfo delChanges = { DataShareObserver::ChangeType::DELETE, { uri }, data, sizeof(data) / sizeof(data[0]) }; helper->NotifyChangeExt(delChanges); dataObserver->data.Wait(); @@ -1186,11 +1179,228 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ToAbsSharedResultSet_Test_001, T std::shared_ptr absSharedResultSet = RdbDataAbilityAdapter::RdbDataAbilityUtils::ToAbsSharedResultSet(resultSet); int rowCount = 0; - if (absSharedResultSet!= nullptr) { + if (absSharedResultSet != nullptr) { absSharedResultSet->GetRowCount(rowCount); } EXPECT_EQ(rowCount, 1); LOG_INFO("MediaDataShare_ToAbsSharedResultSet_Test_001 End"); } + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_ExecuteBatch_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_ExecuteBatch_Test_001::Start"); + std::shared_ptr helper = g_dataShareHelper; + + std::vector statements; + DataShare::OperationStatement statement1; + statement1.operationType = INSERT; + statement1.uri = "datashare:///uri1"; + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("DB_NUM", 150); + valuesBucket.Put("DB_TITLE", "ExecuteBatch_Test002"); + statement1.valuesBucket = valuesBucket; + DataShare::DataSharePredicates predicates; + predicates.SetWhereClause("`DB_NUM` > 100"); + statement1.predicates = predicates; + statements.emplace_back(statement1); + + DataShare::OperationStatement statement2; + statement2.operationType = DELETE; + statement2.uri = "datashareproxy://com.uri2"; + DataShare::DataShareValuesBucket valuesBucket1; + valuesBucket1.Put("DB_TITLE2", "ExecuteBatch_Test002"); + statement2.valuesBucket = valuesBucket1; + DataShare::DataSharePredicates predicates1; + predicates1.SetWhereClause("`DB_TITLE` = ExecuteBatch_Test002"); + statement2.predicates = predicates1; + statements.emplace_back(statement2); + + DataShare::ExecResultSet resultSet; + auto ret = helper->ExecuteBatch(statements, resultSet); + EXPECT_EQ(ret, 0); + LOG_INFO("MediaDataShare_ExecuteBatch_Test_001 End"); +} + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_InsertExt_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_InsertExt_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_CRUD_Test001"); + std::string str; + int ret = helper->InsertExt(uri, valuesBucket, str); + EXPECT_EQ(ret, 0); + LOG_INFO("MediaDataShare_InsertExt_Test_001 End"); +} + +HWTEST_F(MediaDataShareUnitTest, MediaDataShare_TransferUri_Test_001, TestSize.Level0) +{ + LOG_INFO("MediaDataShare_TransferUri_Test_001::Start"); + Uri uri(FILE_DATA_URI); + + auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + EXPECT_NE(saManager, nullptr); + if (saManager == nullptr) { + LOG_ERROR("GetSystemAbilityManager get samgr failed."); + } + auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID); + EXPECT_NE(remoteObj, nullptr); + if (remoteObj == nullptr) { + LOG_ERROR("GetSystemAbility service failed."); + } + std::shared_ptr helper = DataShare::DataShareHelper::Creator(remoteObj, FILE_DATA_URI); + EXPECT_NE(helper, nullptr); + LOG_INFO("MediaDataShare_TransferUri_Test_001 End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperInsertExtControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperInsertExtControllerNullTest_001::Start"); + auto helper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + DataShare::DataShareValuesBucket valuesBucket; + double valueD1 = 20.07; + valuesBucket.Put("phoneNumber", valueD1); + valuesBucket.Put("name", "dataShareTest003"); + int value1 = 1001; + valuesBucket.Put("age", value1); + std::string result; + int retVal = helper->InsertExt(uri, valuesBucket, result); + EXPECT_EQ((retVal < 0), true); + LOG_INFO("ControllerTest_HelperInsertExtControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperUpdateControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperUpdateControllerNullTest_001::Start"); + auto helper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + DataShare::DataSharePredicates predicates; + predicates.EqualTo("name", "Datashare_CRUD_Test001"); + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("name", "Datashare_CRUD_Test002"); + int retVal = helper->Update(uri, predicates, valuesBucket); + EXPECT_EQ((retVal < 0), true); + LOG_INFO("ControllerTest_HelperUpdateControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperDeleteControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperDeleteControllerNullTest_001::Start"); + auto helper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + DataShare::DataSharePredicates deletePredicates; + deletePredicates.EqualTo("age", 1112); + int retVal = helper->Delete(uri, deletePredicates); + EXPECT_EQ((retVal < 0), true); + LOG_INFO("ControllerTest_HelperDeleteControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperQueryControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperQueryControllerNullTest_001::Start"); + auto helper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + DataShare::DataSharePredicates predicates; + predicates.EqualTo("name", "dataShareTest003"); + predicates.Limit(1, 0); + vector columns; + auto resultSet = helper->Query(uri, predicates, columns); + EXPECT_EQ(resultSet, nullptr); + LOG_INFO("ControllerTest_HelperQueryControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperBatchInsertControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperBatchInsertControllerNullTest_001::Start"); + auto helper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + DataShare::DataShareValuesBucket valuesBucket1; + valuesBucket1.Put("name", "dataShareTest006"); + valuesBucket1.Put("phoneNumber", 20.6); + DataShare::DataShareValuesBucket valuesBucket2; + valuesBucket2.Put("name", "dataShareTest007"); + valuesBucket2.Put("phoneNumber", 20.5); + std::vector values; + values.push_back(valuesBucket1); + values.push_back(valuesBucket2); + int result = helper->BatchInsert(uri, values); + EXPECT_EQ((result < 0), true); + LOG_INFO("ControllerTest_HelperBatchInsertControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperExecuteBatchControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperExecuteBatchControllerNullTest_001::Start"); + auto helper= CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(DATA_SHARE_URI); + helper->Release(); + std::vector statements; + DataShare::OperationStatement statement1; + statement1.operationType = INSERT; + statement1.uri = "datashare:///uri1"; + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("DB_NUM", 150); + valuesBucket.Put("DB_TITLE", "ExecuteBatch_Test002"); + statement1.valuesBucket = valuesBucket; + DataShare::DataSharePredicates predicates; + predicates.SetWhereClause("`DB_NUM` > 100"); + statement1.predicates = predicates; + statements.emplace_back(statement1); + + DataShare::OperationStatement statement2; + statement2.operationType = DELETE; + statement2.uri = "datashareproxy://com.uri2"; + DataShare::DataShareValuesBucket valuesBucket1; + valuesBucket1.Put("DB_TITLE2", "ExecuteBatch_Test002"); + statement2.valuesBucket = valuesBucket1; + DataShare::DataSharePredicates predicates1; + predicates1.SetWhereClause("`DB_TITLE` = ExecuteBatch_Test002"); + statement2.predicates = predicates1; + statements.emplace_back(statement2); + + DataShare::ExecResultSet resultSet; + auto ret = helper->ExecuteBatch(statements, resultSet); + EXPECT_EQ((ret < 0), true); + LOG_INFO("ControllerTest_HelperExecuteBatchControllerNullTest_001::End"); +} + +HWTEST_F(MediaDataShareUnitTest, ControllerTest_HelperRegisterObserverControllerNullTest_001, TestSize.Level0) +{ + LOG_INFO("ControllerTest_HelperRegisterObserverControllerNullTest_001 start"); + auto helper= CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID); + ASSERT_TRUE(helper != nullptr); + Uri uri(MEDIALIBRARY_DATA_URI); + helper->Release(); + sptr dataObserver; + helper->RegisterObserver(uri, dataObserver); + + DataShare::DataShareValuesBucket valuesBucket; + valuesBucket.Put("name", "Datashare_Observer_Test001"); + int retVal = helper->Insert(uri, valuesBucket); + EXPECT_EQ((retVal < 0), true); + helper->NotifyChange(uri); + + DataShare::DataSharePredicates deletePredicates; + deletePredicates.EqualTo("name", "Datashare_Observer_Test001"); + retVal = helper->Delete(uri, deletePredicates); + EXPECT_EQ((retVal < 0), true); + helper->NotifyChange(uri); + helper->UnregisterObserver(uri, dataObserver); + LOG_INFO("ControllerTest_HelperRegisterObserverControllerNullTest_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 45dd14d5..b1470258 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 @@ -111,6 +111,7 @@ void SlientAccessTest::TearDownTestCase(void) { auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0); AccessTokenKit::DeleteToken(tokenId); + g_slientAccessHelper = nullptr; } void SlientAccessTest::SetUp(void) {} diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index 3b5839ad..1d4318ba 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -70,14 +70,16 @@ "kv_store", "ipc", "napi", + "netmanager_base", "os_account", "relational_store", "safwk", "samgr", - "udmf" + "udmf", + "app_file_service" ], "third_party": [ - "cjson", + "cJSON", "jsoncpp", "libuv", "openssl", diff --git a/datamgr_service/datamgr_service.gni b/datamgr_service/datamgr_service.gni index ac2f5ccb..8a79ca9d 100644 --- a/datamgr_service/datamgr_service.gni +++ b/datamgr_service/datamgr_service.gni @@ -32,6 +32,8 @@ ipc_core_path = "//foundation/communication/ipc/interfaces/innerkits/ipc_core" device_manager_path = "//foundation/distributedhardware/device_manager" +file_service_path = "//foundation/filemanagement/app_file_service" + data_service_path = "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice" udmf_path = "//foundation/distributeddatamgr/udmf" diff --git a/datamgr_service/hisysevent.yaml b/datamgr_service/hisysevent.yaml index 44a9a785..daba8439 100644 --- a/datamgr_service/hisysevent.yaml +++ b/datamgr_service/hisysevent.yaml @@ -100,6 +100,15 @@ DATABASE_BEHAVIOUR: STORE_ID: {type: STRING, desc: store id } BEHAVIOUR_INFO: {type: STRING, desc: behaviour type and behaviour resulte } +UDMF_DATA_BEHAVIOR: + __BASE: {type: BEHAVIOR, level: MINOR, desc: The event is behaviour record } + APP_ID: {type: STRING, desc: app id } + CHANNEL: {type: STRING, desc: channel name } + DATA_SIZE: {type: INT64, desc: data size } + DATA_TYPE: {type: STRING, desc: data type } + OPERATION: {type: STRING, desc: data operation } + RESULT: {type: STRING, desc: data operation result } + OPEN_DATABASE_FAILED: __BASE: {type: FAULT, level: CRITICAL, desc: The database open failed} APP_ID: {type: STRING, desc: app id } diff --git a/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt b/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt index 06cbff30..af998470 100644 --- a/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/adapter/CMakeLists.txt @@ -20,6 +20,7 @@ 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}/utils/src adapterSrc) +list(REMOVE_ITEM adapterSrc "${CMAKE_CURRENT_SOURCE_DIR}/account/src/account_delegate_default_impl.cpp") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../framework/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/account/src) 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 986bf442..7c6d0282 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 @@ -23,7 +23,7 @@ namespace { constexpr const char *DEFAULT_OHOS_ACCOUNT_UID = ""; // default UID } -//AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateDefaultImpl::GetBaseInstance; +AccountDelegate::BaseInstance AccountDelegate::getInstance_ = AccountDelegateDefaultImpl::GetBaseInstance; AccountDelegate *AccountDelegateDefaultImpl::GetBaseInstance() { static AccountDelegateDefaultImpl accountDelegate; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn index 451b8de6..e6a942ce 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn @@ -24,6 +24,7 @@ ohos_static_library("distributeddata_communicator_static") { "src/communication_provider_impl.cpp", "src/communication_provider_impl.h", "src/communication_strategy.cpp", + "src/communicator_context.cpp", "src/data_buffer.cpp", "src/device_manager_adapter.cpp", "src/process_communicator_impl.cpp", @@ -59,6 +60,8 @@ ohos_static_library("distributeddata_communicator_static") { "device_manager:devicemanagersdk", "dsoftbus:softbus_client", "hilog:libhilog", + "ipc:ipc_core", + "netmanager_base:net_conn_manager_if", ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp index 5a02eb33..c29f60aa 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp @@ -43,10 +43,10 @@ AppPipeHandler::AppPipeHandler(const PipeInfo &pipeInfo) softbusAdapter_ = SoftBusAdapter::GetInstance(); } -Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) +Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - return softbusAdapter_->SendData(pipeInfo, deviceId, ptr, size, info); + return softbusAdapter_->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status AppPipeHandler::StartWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h index 5fe49b7e..2a2508c5 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h @@ -42,8 +42,8 @@ public: // stop DataChangeListener to watch data change; Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); void SetMessageTransFlag(const PipeInfo &pipeInfo, bool flag); diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp index d6580c8b..f3794147 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp @@ -58,15 +58,15 @@ Status AppPipeMgr::StopWatchDataChange(const AppDataChangeListener *observer, co } // Send data to other device, function will be called back after sent to notify send result. -Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) +Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - if (size > DataBuffer::MAX_TRANSFER_SIZE || size <= 0 || ptr == nullptr || + if (dataInfo.length > DataBuffer::MAX_TRANSFER_SIZE || dataInfo.length == 0 || dataInfo.data == nullptr || pipeInfo.pipeId.empty() || deviceId.deviceId.empty()) { - ZLOGW("Input is invalid, maxSize:%d, current size:%d", DataBuffer::MAX_TRANSFER_SIZE, size); + ZLOGW("Input is invalid, maxSize:%u, current size:%u", DataBuffer::MAX_TRANSFER_SIZE, dataInfo.length); return Status::ERROR; } - ZLOGD("pipeInfo:%s ,size:%d", pipeInfo.pipeId.c_str(), size); + ZLOGD("pipeInfo:%s ,size:%u, total length:%u", pipeInfo.pipeId.c_str(), dataInfo.length, totalLength); std::shared_ptr appPipeHandler; { std::lock_guard lock(dataBusMapMutex_); @@ -77,7 +77,7 @@ Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, } appPipeHandler = it->second; } - return appPipeHandler->SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeHandler->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } // start server diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h index c942cd46..222248c5 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h @@ -36,8 +36,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); // start server Status Start(const PipeInfo &pipeInfo); // stop server diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp index 75b71e64..ee654fcc 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp @@ -48,10 +48,10 @@ Status CommunicationProviderImpl::StopWatchDataChange(const AppDataChangeListene return appPipeMgr_.StopWatchDataChange(observer, pipeInfo); } -Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, - int size, const MessageInfo &info) +Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - return appPipeMgr_.SendData(pipeInfo, deviceId, ptr, size, info); + return appPipeMgr_.SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } Status CommunicationProviderImpl::Start(const PipeInfo &pipeInfo) diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h index 469a7101..edac68dc 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h @@ -36,8 +36,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) override; // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info) override; + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) override; // start 1 server to listen data from other devices; Status Start(const PipeInfo &pipeInfo) override; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp new file mode 100644 index 00000000..850a052c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "communicator_context.h" + +namespace OHOS::DistributedData { +CommunicatorContext &CommunicatorContext::getInstance() +{ + static CommunicatorContext context; + return context; +} + +void CommunicatorContext::SetThreadPool(std::shared_ptr executors) +{ + executors_ = executors; +} + +std::shared_ptr CommunicatorContext::GetThreadPool() +{ + return executors_; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp index 84d2f95a..49dd5459 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.cpp @@ -19,14 +19,6 @@ namespace OHOS { namespace AppDistributedKv { int DataBuffer::sequence_ = 0; -const size_t DataBuffer::MAX_DATA_LEN = 1024 * 1024 * 5; - -const int DataBuffer::MAX_TRANSFER_SIZE = 1024 * 1024 * 5 - DataBuffer::HEADER_LEN; - -const uint32_t DataBuffer::VERSION = 0; - -const uint32_t DataBuffer::TYPE = 0; - DataBuffer::DataBuffer() : buf_(nullptr), size_(0), used_(0) {} diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.h index 1a7627c1..e56d8915 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/data_buffer.h @@ -45,17 +45,17 @@ public: size_t GetBufUsed() const; // header length - static const int HEADER_LEN = sizeof(HeaderInfo); + static const uint32_t HEADER_LEN = sizeof(HeaderInfo); // max size for transferring data using pipe is 5M - static const size_t MAX_DATA_LEN; + static constexpr size_t MAX_DATA_LEN = 1024 * 1024 * 5; // 5M; max size for transfer using pipe (12 is header length, rest is data wait for transferring) - static const int MAX_TRANSFER_SIZE; + static constexpr uint32_t MAX_TRANSFER_SIZE = 1024 * 1024 * 5 - HEADER_LEN; - static const uint32_t VERSION; + static constexpr uint32_t VERSION = 0; - static const uint32_t TYPE; + static constexpr uint32_t TYPE = 0; private: char *buf_; 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 2ea67eb8..1ac478c1 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 @@ -15,13 +15,19 @@ #define LOG_TAG "DeviceManagerAdapter" #include "device_manager_adapter.h" + #include -#include "log_print.h" + #include "kvstore_utils.h" +#include "log_print.h" +#include "net_conn_callback_stub.h" +#include "net_conn_client.h" +#include "net_handle.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedHardware; using namespace OHOS::AppDistributedKv; +using namespace OHOS::NetManagerStandard; using KvStoreUtils = OHOS::DistributedKv::KvStoreUtils; constexpr int32_t DM_OK = 0; constexpr const char *PKG_NAME = "ohos.distributeddata.service"; @@ -74,7 +80,66 @@ void DataMgrDmInitCall::OnRemoteDied() dmAdapter_.Init(executors_); } +class NetConnCallbackObserver : public NetConnCallbackStub { +public: + explicit NetConnCallbackObserver(DeviceManagerAdapter &dmAdapter) : dmAdapter_(dmAdapter) {} + ~NetConnCallbackObserver() override = default; + int32_t NetAvailable(sptr &netHandle) override; + int32_t NetCapabilitiesChange(sptr &netHandle, const sptr &netAllCap) override; + int32_t NetConnectionPropertiesChange(sptr &netHandle, const sptr &info) override; + int32_t NetLost(sptr &netHandle) override; + int32_t NetUnavailable() override; + int32_t NetBlockStatusChange(sptr &netHandle, bool blocked) override; + +private: + DeviceManagerAdapter &dmAdapter_; +}; + +int32_t NetConnCallbackObserver::NetAvailable(sptr &netHandle) +{ + ZLOGI("OnNetworkAvailable"); + dmAdapter_.Online(dmAdapter_.cloudDmInfo); + dmAdapter_.isNetAvailable_ = true; + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetUnavailable() +{ + ZLOGI("OnNetworkUnavailable"); + dmAdapter_.isNetAvailable_ = false; + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetCapabilitiesChange(sptr &netHandle, + const sptr &netAllCap) +{ + ZLOGI("OnNetCapabilitiesChange"); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetConnectionPropertiesChange(sptr &netHandle, + const sptr &info) +{ + ZLOGI("OnNetConnectionPropertiesChange"); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetLost(sptr &netHandle) +{ + ZLOGI("OnNetLost"); + dmAdapter_.isNetAvailable_ = false; + dmAdapter_.Offline(dmAdapter_.cloudDmInfo); + return DistributedKv::SUCCESS; +} + +int32_t NetConnCallbackObserver::NetBlockStatusChange(sptr &netHandle, bool blocked) +{ + ZLOGI("OnNetBlockStatusChange"); + return DistributedKv::SUCCESS; +} + DeviceManagerAdapter::DeviceManagerAdapter() + : cloudDmInfo({ "cloudDeviceId", "cloudDeviceName", 0, "cloudNetworkId", 0 }) { ZLOGI("construct"); } @@ -107,11 +172,12 @@ std::function DeviceManagerAdapter::RegDevCallback() auto dmInitCall = std::make_shared(*this, executors_); auto resultInit = devManager.InitDeviceManager(PKG_NAME, dmInitCall); auto resultState = devManager.RegisterDevStateCallback(PKG_NAME, "", dmStateCall); - if (resultInit == DM_OK && resultState == DM_OK) { + auto resultNet = RegOnNetworkChange(); + if (resultInit == DM_OK && resultState == DM_OK && resultNet) { return; } constexpr int32_t INTERVAL = 500; - executors_->Schedule(RegDevCallback(), std::chrono::milliseconds(INTERVAL)); + executors_->Schedule(std::chrono::milliseconds(INTERVAL), RegDevCallback()); }; } @@ -153,6 +219,7 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d", KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_ONLINE); + syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); auto observers = GetObservers(); for (const auto &item : observers) { // notify db if (item == nullptr) { @@ -171,12 +238,11 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE); } } - executors_->Schedule( - std::chrono::milliseconds(SYNC_TIMEOUT), - [this, dvInfo]() { - TimeOut(dvInfo.uuid); - }); - syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); + + executors_->Schedule(std::chrono::milliseconds(SYNC_TIMEOUT), [this, dvInfo]() { + TimeOut(dvInfo.uuid); + }); + for (const auto &item : observers) { // set compatible identify, sync service meta if (item == nullptr) { continue; @@ -193,7 +259,7 @@ void DeviceManagerAdapter::TimeOut(const std::string uuid) ZLOGE("uuid empty!"); return; } - if (syncTask_.Contains(uuid)) { + if (syncTask_.Contains(uuid) && uuid != CLOUD_DEVICE_UUID) { ZLOGI("[TimeOutReadyEvent] uuid:%{public}s", KvStoreUtils::ToBeAnonymous(uuid).c_str()); std::string event = R"({"extra": {"deviceId":")" + uuid + R"(" } })"; DeviceManager::GetInstance().NotifyEvent(PKG_NAME, DmNotifyEvent::DM_NOTIFY_EVENT_ONDEVICEREADY, event); @@ -404,6 +470,9 @@ std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkI if (networkId.empty()) { return ""; } + if (networkId == DeviceManagerAdapter::cloudDmInfo.networkId) { + return CLOUD_DEVICE_UUID; + } DeviceInfo dvInfo; if (deviceInfos_.Get(networkId, dvInfo)) { return dvInfo.uuid; @@ -422,6 +491,9 @@ std::string DeviceManagerAdapter::GetUdidByNetworkId(const std::string &networkI if (networkId.empty()) { return ""; } + if (networkId == DeviceManagerAdapter::cloudDmInfo.networkId) { + return CLOUD_DEVICE_UDID; + } DeviceInfo dvInfo; if (deviceInfos_.Get(networkId, dvInfo)) { return dvInfo.udid; @@ -451,7 +523,7 @@ std::vector DeviceManagerAdapter::ToUUID(const std::vector DeviceManagerAdapter::ToUUID(std::vector de std::vector uuids; for (auto &device : devices) { if (device.uuid.empty()) { - continue ; + continue; } uuids.push_back(std::move(device.uuid)); } @@ -488,4 +560,24 @@ std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const } return encryptedUuid; } + +bool DeviceManagerAdapter::RegOnNetworkChange() +{ + sptr observer = new (std::nothrow) NetConnCallbackObserver(*this); + if (observer == nullptr) { + ZLOGE("new operator error.observer is nullptr"); + return false; + } + int nRet = NetConnClient::GetInstance().RegisterNetConnCallback(observer); + if (nRet != NETMANAGER_SUCCESS) { + ZLOGE("RegisterNetConnCallback failed, ret = %{public}d", nRet); + return false; + } + return true; +} + +bool DeviceManagerAdapter::IsNetworkAvailable() +{ + return isNetAvailable_; +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index c93a2a97..4b435d1e 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -111,11 +111,19 @@ DBStatus ProcessCommunicatorImpl::RegOnDataReceive(const OnDataReceive &callback } DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) +{ + uint32_t totalLength = 0; + return SendData(dstDevInfo, data, length, totalLength); +} + +DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, + uint32_t totalLength) { PipeInfo pi = {thisProcessLabel_, ""}; + const DataInfo dataInfo = { const_cast(data), length}; DeviceId destination; destination.deviceId = dstDevInfo.identifier; - Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, data, static_cast(length)); + Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); if (errCode != Status::SUCCESS) { ZLOGE("commProvider_ SendData Fail."); return DBStatus::DB_ERROR; 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 868d5ed1..2cd755e0 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -46,8 +46,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *data, int size, - const MessageInfo &info); + Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); 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 d7c2d786..9f795a78 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 @@ -38,6 +38,7 @@ enum SoftBusAdapterErrorCode : int32_t { PEER_SESSION_NAME_INVALID, PEER_DEVICE_ID_INVALID, SESSION_SIDE_INVALID, + ROUTE_TYPE_INVALID, }; constexpr int32_t SESSION_NAME_SIZE_MAX = 65; constexpr int32_t DEVICE_ID_SIZE_MAX = 65; @@ -52,6 +53,7 @@ struct ConnDetailsInfo { char peerName[SESSION_NAME_SIZE_MAX] = ""; std::string peerDevUuid; int32_t side = -1; + int32_t routeType = -1; }; class AppDataListenerWrap { public: @@ -160,8 +162,8 @@ Status SoftBusAdapter::StopWatchDataChange(__attribute__((unused)) const AppData return Status::ERROR; } -Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *data, int size, - const MessageInfo &info) +Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { std::shared_ptr conn; { @@ -176,7 +178,7 @@ Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &device } if (conn != nullptr) { - return conn->Send(data, size); + return conn->Send(dataInfo, totalLength); } return Status::ERROR; @@ -359,6 +361,13 @@ int AppDataListenerWrap::GetConnDetailsInfo(int connId, ConnDetailsInfo &connInf return SESSION_SIDE_INVALID; } + int32_t routeType = RouteType::INVALID_ROUTE_TYPE; + ret = GetSessionOption(connId, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + if (ret != SOFTBUS_OK) { + return ROUTE_TYPE_INVALID; + } + connInfo.routeType = routeType; + return SOFTBUS_OK; } @@ -379,8 +388,8 @@ int AppDataListenerWrap::OnConnectOpened(int connId, int result) } ZLOGD("[OnConnectOpened] conn id:%{public}d, my name:%{public}s, peer name:%{public}s, " - "peer devId:%{public}s, side:%{public}d", connId, connInfo.myName, connInfo.peerName, - KvStoreUtils::ToBeAnonymous(connInfo.peerDevUuid).c_str(), connInfo.side); + "peer devId:%{public}s, side:%{public}d, routeType:%{public}d", connId, connInfo.myName, connInfo.peerName, + KvStoreUtils::ToBeAnonymous(connInfo.peerDevUuid).c_str(), connInfo.side, connInfo.routeType); return 0; } 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 fe9601d6..98d9f15d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "SoftBusClient" +#include "communicator_context.h" #include "device_manager_adapter.h" #include "kvstore_utils.h" #include "log_print.h" @@ -23,6 +24,7 @@ namespace OHOS::AppDistributedKv { using namespace OHOS::DistributedKv; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using Context = DistributedData::CommunicatorContext; SoftBusClient::SoftBusClient(const PipeInfo &pipeInfo, const DeviceId &deviceId, const std::function &getConnStatus) : pipe_(pipeInfo), device_(deviceId), getConnStatus_(getConnStatus) @@ -51,6 +53,7 @@ void SoftBusClient::RestoreDefaultValue() { connId_ = INVALID_CONNECT_ID; status_ = ConnectStatus::DISCONNECT; + routeType_ = RouteType::INVALID_ROUTE_TYPE; strategy_ = Strategy::DEFAULT; mtu_ = DEFAULT_MTU_SIZE; } @@ -61,48 +64,116 @@ uint32_t SoftBusClient::GetMtuSize() const return mtu_; } -Status SoftBusClient::Send(const uint8_t *data, int size) +Status SoftBusClient::Send(const DataInfo &dataInfo, uint32_t totalLength) { std::lock_guard lock(mutex_); - auto result = OpenConnect(); + auto result = OpenConnect(totalLength); if (result != Status::SUCCESS) { return result; } - ZLOGD("send data connId:%{public}d, data size:%{public}d.", connId_, size); - int32_t ret = SendBytes(connId_, data, size); + ZLOGD("send data connId:%{public}d, data size:%{public}u, total length:%{public}u.", + connId_, dataInfo.length, totalLength); + int32_t ret = SendBytes(connId_, dataInfo.data, dataInfo.length); if (ret != SOFTBUS_OK) { ZLOGE("send data to connId%{public}d failed, ret:%{public}d.", connId_, ret); return Status::ERROR; } + if (routeType_ == RouteType::WIFI_P2P) { + UpdateP2pFinishTime(connId_, dataInfo.length); + } return Status::SUCCESS; } -Status SoftBusClient::OpenConnect() +Status SoftBusClient::OpenConnect(uint32_t totalLength) { + strategy_ = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); if (status_ == ConnectStatus::CONNECT_OK) { - return Status::SUCCESS; + status_ = ConnectStatus::DISCONNECT; + auto result = SwitchChannel(totalLength); + if (result == Status::SUCCESS) { + status_ = ConnectStatus::CONNECT_OK; + } + return result; } - auto result = Open(); + auto result = CreateChannel(totalLength); if (result != Status::SUCCESS) { return result; } status_ = ConnectStatus::CONNECT_OK; - UpdateMtuSize(); return Status::SUCCESS; } -Status SoftBusClient::Open() +Status SoftBusClient::SwitchChannel(uint32_t totalLength) +{ + if (strategy_ == Strategy::BUTT) { + return Status::NETWORK_ERROR; + } + + if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { + return Status::SUCCESS; + } + + if (routeType_ == RouteType::WIFI_STA) { + return Status::SUCCESS; + } + + if (routeType_ == RouteType::BT_BLE || routeType_ == RouteType::BT_BR) { + if (totalLength < P2P_SIZE_THRESHOLD) { + return Status::SUCCESS; + } + + ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to wifi or p2p.", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); + RestoreDefaultValue(); + return Open(GetSessionAttribute(true)); + } + + if (routeType_ == RouteType::WIFI_P2P) { + if (totalLength > P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR) { + return Status::SUCCESS; + } + + ZLOGD("switch %{public}s,session:%{public}s,connId:%{public}d,routeType:%{public}d to ble or br.", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); + { + std::lock_guard lock(taskMutex_); + if (closeP2pTaskId_ == ExecutorPool::INVALID_TASK_ID) { + closeP2pTaskId_ = Context::getInstance(). + GetThreadPool()->Execute(std::bind(&SoftBusClient::CloseP2pSessions, this)); + } + } + RestoreDefaultValue(); + return Open(GetSessionAttribute(false)); + } + + return Status::NETWORK_ERROR; +} + +Status SoftBusClient::CreateChannel(uint32_t totalLength) +{ + if (strategy_ == Strategy::BUTT) { + return Status::NETWORK_ERROR; + } + + if (strategy_ == Strategy::ON_LINE_SELECT_CHANNEL) { + return Open(GetSessionAttribute(true)); + } + + if (totalLength < P2P_SIZE_THRESHOLD) { + return Open(GetSessionAttribute(false)); + } + return Open(GetSessionAttribute(true)); +} + +Status SoftBusClient::Open(SessionAttribute attr) { - Strategy strategy = CommunicationStrategy::GetInstance().GetStrategy(device_.deviceId); - SessionAttribute attr = { 0 }; - InitSessionAttribute(strategy, attr); int id = OpenSession(pipe_.pipeId.c_str(), pipe_.pipeId.c_str(), DmAdapter::GetInstance().ToNetworkID(device_.deviceId).c_str(), "GROUP_ID", &attr); ZLOGI("open %{public}s,session:%{public}s,connId:%{public}d,linkNum:%{public}d,strategy:%{public}d", - KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), id, attr.linkTypeNum, strategy); + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), id, attr.linkTypeNum, strategy_); if (id < 0) { ZLOGW("Open %{public}s, type:%{public}d failed, connId:%{public}d", pipe_.pipeId.c_str(), attr.dataType, id); @@ -110,22 +181,34 @@ Status SoftBusClient::Open() } connId_ = id; - strategy_ = strategy; int state = getConnStatus_(connId_); ZLOGI("waited for notification, state:%{public}d connId:%{public}d", state, id); if (state != SOFTBUS_OK) { ZLOGE("open callback result error"); return Status::NETWORK_ERROR; } + + int32_t routeType = RouteType::INVALID_ROUTE_TYPE; + auto ret = GetSessionOption(connId_, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); + if (ret != SOFTBUS_OK) { + ZLOGE("get routeType failed, session:%{public}s, connId:%{public}d", pipe_.pipeId.c_str(), connId_); + return Status::NETWORK_ERROR; + } + routeType_ = routeType; + + UpdateMtuSize(); + ZLOGI("open %{public}s, session:%{public}s success, connId:%{public}d, routeType:%{public}d", + KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), connId_, routeType_); return Status::SUCCESS; } -void SoftBusClient::InitSessionAttribute(Strategy strategy, SessionAttribute &attr) +SessionAttribute SoftBusClient::GetSessionAttribute(bool isP2p) { + SessionAttribute attr; attr.dataType = TYPE_BYTES; // If the dataType is BYTES, the default strategy is wifi_5G > wifi_2.4G > BR, without P2P; - if (strategy == Strategy::DEFAULT) { - return; + if (!isP2p) { + return attr; } int index = 0; @@ -134,6 +217,7 @@ void SoftBusClient::InitSessionAttribute(Strategy strategy, SessionAttribute &at attr.linkType[index++] = LINK_TYPE_WIFI_P2P; attr.linkType[index++] = LINK_TYPE_BR; attr.linkTypeNum = index; + return attr; } void SoftBusClient::UpdateMtuSize() @@ -155,4 +239,44 @@ void SoftBusClient::AfterStrategyUpdate(Strategy strategy) RestoreDefaultValue(); } } + +void SoftBusClient::CloseP2pSessions() +{ + Time now = std::chrono::steady_clock::now(); + Time nextClose = std::chrono::steady_clock::time_point::max(); + p2pFinishTime_.EraseIf([&now, &nextClose](const int32_t &connId, Time &finishTime) -> bool { + if (finishTime + P2P_CLOSE_DELAY <= now) { + ZLOGD("close timeout p2p connId:%{public}d", connId); + CloseSession(connId); + return true; + } + + if (finishTime + P2P_CLOSE_DELAY < nextClose) { + nextClose = finishTime + P2P_CLOSE_DELAY; + } + return false; + }); + + std::lock_guard lock(taskMutex_); + if (!p2pFinishTime_.Empty()) { + closeP2pTaskId_ = Context::getInstance().GetThreadPool()->Schedule(nextClose - now, + std::bind(&SoftBusClient::CloseP2pSessions, this)); + } else { + closeP2pTaskId_ = ExecutorPool::INVALID_TASK_ID; + } +} + +void SoftBusClient::UpdateP2pFinishTime(int32_t connId, uint32_t dataLength) +{ + Time now = std::chrono::steady_clock::now(); + auto delay = std::chrono::microseconds(dataLength / P2P_TRANSFER_PER_MICROSECOND); + p2pFinishTime_.Compute(connId, [&now, &delay](const auto &id, auto &finishTime) -> bool { + if (finishTime < now) { + finishTime = now + delay; + } else { + finishTime += delay; + } + return true; + }); +} } \ No newline at end of file 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 4a434606..bd2c086c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -19,7 +19,9 @@ #include #include +#include "commu_types.h" #include "communication_strategy.h" +#include "executor_pool.h" #include "session.h" #include "softbus_bus_center.h" namespace OHOS::AppDistributedKv { @@ -30,7 +32,7 @@ public: ~SoftBusClient(); using Strategy = CommunicationStrategy::Strategy; - Status Send(const uint8_t *data, int size); + Status Send(const DataInfo &dataInfo, uint32_t totalLength); bool operator==(int32_t connId) const; bool operator==(const std::string &deviceId) const; uint32_t GetMtuSize() const; @@ -41,22 +43,35 @@ private: DISCONNECT, }; - Status OpenConnect(); - Status Open(); - void InitSessionAttribute(Strategy strategy, SessionAttribute &attr); + using Time = std::chrono::steady_clock::time_point; + Status OpenConnect(uint32_t totalLength); + Status SwitchChannel(uint32_t totalLength); + Status CreateChannel(uint32_t totalLength); + Status Open(SessionAttribute attr); + SessionAttribute GetSessionAttribute(bool isP2p); void RestoreDefaultValue(); void UpdateMtuSize(); + void CloseP2pSessions(); + void UpdateP2pFinishTime(int32_t connId, uint32_t dataLength); static constexpr int32_t INVALID_CONNECT_ID = -1; static constexpr uint32_t WAIT_MAX_TIME = 10; static constexpr uint32_t DEFAULT_MTU_SIZE = 4096u; + static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB + static constexpr uint32_t P2P_TRANSFER_PER_MICROSECOND = 10; // 10 bytes per microsecond + static constexpr float SWITCH_DELAY_FACTOR = 0.6f; + static constexpr std::chrono::steady_clock::duration P2P_CLOSE_DELAY = std::chrono::seconds(3); int32_t connId_ = INVALID_CONNECT_ID; + int32_t routeType_ = RouteType::INVALID_ROUTE_TYPE; Strategy strategy_ = Strategy::DEFAULT; ConnectStatus status_ = ConnectStatus::DISCONNECT; std::mutex mutex_; + std::mutex taskMutex_; PipeInfo pipe_; DeviceId device_; uint32_t mtu_; + ConcurrentMap p2pFinishTime_; + ExecutorPool::TaskId closeP2pTaskId_ = ExecutorPool::INVALID_TASK_ID; std::function getConnStatus_; }; } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp index 137f105c..0000371d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp @@ -132,7 +132,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider005, TestSize.Level std::string content = "Helloworlds"; const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di17 = {"127.0.0.2"}; - Status status = CommunicationProvider::GetInstance().SendData(id17, di17, t, content.length()); + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); EXPECT_NE(status, Status::SUCCESS); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener17, id17); CommunicationProvider::GetInstance().Stop(id17); diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp index 9e3b4619..7632db6c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.cpp @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "behaviour_reporter_impl.h" namespace OHOS { @@ -22,6 +21,13 @@ ReportStatus BehaviourReporterImpl::Report(const BehaviourMsg &msg) HiViewAdapter::ReportBehaviour(DfxCodeConstant::DATABASE_BEHAVIOUR, msg, executors_); return ReportStatus::SUCCESS; } + +ReportStatus BehaviourReporterImpl::UDMFReport(const UdmfBehaviourMsg &msg) +{ + HiViewAdapter::ReportUdmfBehaviour(DfxCodeConstant::UDMF_DATA_BEHAVIOR, msg, executors_); + return ReportStatus::SUCCESS; +} + void BehaviourReporterImpl::SetThreadPool(std::shared_ptr executors) { executors_ = executors; diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h b/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h index 7ac010b1..5fff69e4 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/behaviour/behaviour_reporter_impl.h @@ -25,6 +25,7 @@ class BehaviourReporterImpl : public BehaviourReporter { public: virtual ~BehaviourReporterImpl() {} ReportStatus Report(const struct BehaviourMsg &msg) override; + ReportStatus UDMFReport(const UdmfBehaviourMsg &msg) override; void SetThreadPool(std::shared_ptr executors); private: diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h b/datamgr_service/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h index a78caaaf..cc2cba1d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/dfx_code_constant.h @@ -32,5 +32,6 @@ public: static inline const int DATABASE_CORRUPTED_FAILED = 950001113; static inline const int DATABASE_REKEY_FAILED = 950001114; static inline const int DATABASE_BEHAVIOUR = 950001115; + static inline const int UDMF_DATA_BEHAVIOR = 950001116; }; #endif // DISTRIBUTEDDATAMGR_DFX_CODE_CONSTANT_H diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp index 9ac6fef2..47aa3016 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp @@ -47,6 +47,11 @@ constexpr const char *TAG = "TAG"; constexpr const char *POWERSTATS = "PowerStats"; // behaviour key constexpr const char *BEHAVIOUR_INFO = "BEHAVIOUR_INFO"; +constexpr const char *CHANNEL = "CHANNEL"; +constexpr const char *DATA_SIZE = "DATA_SIZE"; +constexpr const char *DATA_TYPE = "DATA_TYPE"; +constexpr const char *OPERATION = "OPERATION"; +constexpr const char *RESULT = "RESULT"; const std::map EVENT_COVERT_TABLE = { { DfxCodeConstant::SERVICE_FAULT, "SERVICE_FAULT" }, @@ -63,6 +68,7 @@ const std::map EVENT_COVERT_TABLE = { { DfxCodeConstant::DATABASE_CORRUPTED_FAILED, "DATABASE_CORRUPTED_FAILED" }, { DfxCodeConstant::DATABASE_REKEY_FAILED, "DATABASE_REKEY_FAILED" }, { DfxCodeConstant::DATABASE_BEHAVIOUR, "DATABASE_BEHAVIOUR" }, + { DfxCodeConstant::UDMF_DATA_BEHAVIOR, "UDMF_DATA_BEHAVIOR" }, }; } using OHOS::HiviewDFX::HiSysEvent; @@ -298,6 +304,27 @@ void HiViewAdapter::ReportApiPerformanceStatistic(int dfxCode, const ApiPerforma StartTimerThread(executors); } +void HiViewAdapter::ReportUdmfBehaviour( + int dfxCode, const UdmfBehaviourMsg &msg, std::shared_ptr executors) +{ + if (executors == nullptr) { + ZLOGI("report udmf behavior failed"); + return; + } + ExecutorPool::Task task([dfxCode, msg]() { + HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, + CoverEventID(dfxCode), + HiSysEvent::EventType::BEHAVIOR, + APP_ID, msg.appId, + CHANNEL, msg.channel, + DATA_SIZE, msg.dataSize, + DATA_TYPE, msg.dataType, + OPERATION, msg.operation, + RESULT, msg.result); + }); + executors->Execute(std::move(task)); +} + void HiViewAdapter::InvokeApiPerformance() { std::string message; diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h index 21de2703..cb03b82c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h @@ -46,6 +46,7 @@ public: static void ReportApiPerformanceStatistic(int dfxCode, const ApiPerformanceStat &stat, std::shared_ptr executors); static void ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::shared_ptr executors); + static void ReportUdmfBehaviour(int dfxCode, const UdmfBehaviourMsg &msg, std::shared_ptr executors); static void StartTimerThread(std::shared_ptr executors); private: diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h index ca822697..b39e02be 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -35,6 +35,21 @@ enum DeviceType { OTHERS, }; +enum RouteType : int32_t { + INVALID_ROUTE_TYPE = -1, + ROUTE_TYPE_ALL = 0, + WIFI_STA, + WIFI_P2P, + BT_BR, + BT_BLE, + BUTT, +}; + +struct DataInfo { + uint8_t *data; + uint32_t length; +}; + struct API_EXPORT PipeInfo { std::string pipeId; std::string userId; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h index 0418b0c3..b0295285 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h @@ -45,8 +45,8 @@ public: virtual Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) = 0; // Send data to other device, function will be called back after sent to notify send result - virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const uint8_t *ptr, int size, - const MessageInfo &info = { MessageType::DEFAULT }) = 0; + virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info = { MessageType::DEFAULT }) = 0; // start one server to listen data from other devices; virtual Status Start(const PipeInfo &pipeInfo) = 0; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h new file mode 100644 index 00000000..bcf7ea85 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DISTRIBUTEDDATAMGR_COMMUNICATOR_CONTEXT_H +#define DISTRIBUTEDDATAMGR_COMMUNICATOR_CONTEXT_H + +#include "executor_pool.h" +#include "visibility.h" + +namespace OHOS::DistributedData { +class API_EXPORT CommunicatorContext { +public: + API_EXPORT static CommunicatorContext &getInstance(); + API_EXPORT void SetThreadPool(std::shared_ptr executors); + std::shared_ptr GetThreadPool(); + +private: + CommunicatorContext() = default; + ~CommunicatorContext() = default; + CommunicatorContext(CommunicatorContext const &) = delete; + void operator=(CommunicatorContext const &) = delete; + CommunicatorContext(CommunicatorContext &&) = delete; + CommunicatorContext &operator=(CommunicatorContext &&) = delete; + + std::shared_ptr executors_; +}; +} // namespace OHOS::DistributedData +#endif // DISTRIBUTEDDATAMGR_COMMUNICATOR_CONTEXT_H 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 9cb05a88..1806e569 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 @@ -38,6 +38,8 @@ public: using AppDeviceChangeListener = OHOS::AppDistributedKv::AppDeviceChangeListener; using Status = OHOS::DistributedKv::Status; static DeviceManagerAdapter &GetInstance(); + static constexpr const char *CLOUD_DEVICE_UUID = "cloudDeviceUuid"; + static constexpr const char *CLOUD_DEVICE_UDID = "cloudDeviceUdid"; void Init(std::shared_ptr executors); Status StartWatchDeviceChange(const AppDeviceChangeListener *observer, const PipeInfo &pipeInfo); @@ -54,12 +56,15 @@ public: static std::vector ToUUID(std::vector devices); std::string ToNetworkID(const std::string &id); void NotifyReadyEvent(const std::string &uuid); + bool IsNetworkAvailable(); friend class DataMgrDmStateCall; + friend class NetConnCallbackObserver; private: DeviceManagerAdapter(); ~DeviceManagerAdapter(); std::function RegDevCallback(); + bool RegOnNetworkChange(); bool GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo &dvInfo); void SaveDeviceInfo(const DeviceInfo &deviceInfo, const AppDistributedKv::DeviceChangeType &type); void UpdateDeviceInfo(); @@ -73,12 +78,14 @@ private: std::mutex devInfoMutex_ {}; DeviceInfo localInfo_ {}; + const DmDeviceInfo cloudDmInfo; ConcurrentMap observers_ {}; LRUBucket deviceInfos_ {64}; static constexpr size_t TIME_TASK_CAPACITY = 50; static constexpr int32_t SYNC_TIMEOUT = 10 * 1000; // ms ConcurrentMap syncTask_ {}; std::shared_ptr executors_; + bool isNetAvailable_ = false; }; } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index 26146c6f..259f775e 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -46,6 +46,8 @@ public: DBStatus RegOnDataReceive(const OnDataReceive &callback) override; DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) override; + DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, + uint32_t totalLength) override; uint32_t GetMtuSize() override; uint32_t GetMtuSize(const DeviceInfos &devInfo) override; DeviceInfos GetLocalDeviceInfos() override; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h b/datamgr_service/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h index 57b1f32c..82431c96 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/dfx/behaviour_reporter.h @@ -23,6 +23,7 @@ namespace DistributedDataDfx { class BehaviourReporter { public: KVSTORE_API virtual ReportStatus Report(const BehaviourMsg &msg) = 0; + KVSTORE_API virtual ReportStatus UDMFReport(const UdmfBehaviourMsg &msg) = 0; KVSTORE_API virtual ~BehaviourReporter() {} }; } // namespace DistributedDataDfx diff --git a/datamgr_service/services/distributeddataservice/adapter/include/dfx/dfx_types.h b/datamgr_service/services/distributeddataservice/adapter/include/dfx/dfx_types.h index e8ab47b4..cbc0117d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/dfx/dfx_types.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/dfx/dfx_types.h @@ -131,6 +131,15 @@ struct BehaviourMsg { std::string extensionInfo; }; +struct UdmfBehaviourMsg { + std::string appId; + std::string channel; + int64_t dataSize; + std::string dataType; + std::string operation; + std::string result; +}; + struct VisitStat { std::string appId; std::string interfaceName; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/dfx/reporter.h b/datamgr_service/services/distributeddataservice/adapter/include/dfx/reporter.h index c2537b57..de60c0e8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/dfx/reporter.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/dfx/reporter.h @@ -43,7 +43,7 @@ public: void SetThreadPool(std::shared_ptr executors) { executors_ = executors; - if (executors == nullptr) { + if (executors != nullptr) { ServiceFault(); RuntimeFault(); DatabaseFault(); diff --git a/datamgr_service/services/distributeddataservice/adapter/permission/src/permission_validator.cpp b/datamgr_service/services/distributeddataservice/adapter/permission/src/permission_validator.cpp index f4f58c6d..c05e483f 100644 --- a/datamgr_service/services/distributeddataservice/adapter/permission/src/permission_validator.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/permission/src/permission_validator.cpp @@ -31,22 +31,15 @@ PermissionValidator &PermissionValidator::GetInstance() // check whether the client process have enough privilege to share data with the other devices. bool PermissionValidator::CheckSyncPermission(uint32_t tokenId) { - auto type = AccessTokenKit::GetTokenTypeFlag(tokenId); - if (type == TOKEN_NATIVE || type == TOKEN_SHELL) { - return true; - } - if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_HAP) { - return (AccessTokenKit::VerifyAccessToken(tokenId, DISTRIBUTED_DATASYNC) == PERMISSION_GRANTED); - } - - ZLOGE("token:0x%{public}x", tokenId); - return false; + auto permit = AccessTokenKit::VerifyAccessToken(tokenId, DISTRIBUTED_DATASYNC); + ZLOGD("sync permit:%{public}d, token:0x%{public}x", permit, tokenId); + return permit == PERMISSION_GRANTED; } bool PermissionValidator::IsCloudConfigPermit(uint32_t tokenId) { auto permit = AccessTokenKit::VerifyAccessToken(tokenId, CLOUD_DATA_CONFIG); - ZLOGD("cloud permit: %{public}d", permit); + ZLOGD("cloud permit:%{public}d, token:0x%{public}x", permit, tokenId); return permit == PERMISSION_GRANTED; } } // namespace DistributedKv diff --git a/datamgr_service/services/distributeddataservice/app/BUILD.gn b/datamgr_service/services/distributeddataservice/app/BUILD.gn index 607c6732..ccb08f5b 100644 --- a/datamgr_service/services/distributeddataservice/app/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/BUILD.gn @@ -99,7 +99,6 @@ ohos_shared_library("distributeddataservice") { configs = [ ":module_private_config" ] deps = [ - "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", @@ -124,6 +123,7 @@ ohos_shared_library("distributeddataservice") { "hitrace:libhitracechain", "ipc:ipc_core", "kv_store:distributeddata_inner", + "kv_store:distributeddb", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/datamgr_service/services/distributeddataservice/app/distributed_data.cfg b/datamgr_service/services/distributeddataservice/app/distributed_data.cfg index 45046b10..e8632b4c 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"], + "gid" : ["system","shell","readproc","ddms","dfs_share"], "writepid":[ "/dev/cpuset/foreground/tasks", "/dev/stune/foreground/tasks", @@ -28,11 +28,13 @@ }, "secon" : "u:r:distributeddata:s0", "apl" : "system_basic", + "sandbox" : 0, "permission" : [ "ohos.permission.DISTRIBUTED_DATASYNC", "ohos.permission.MANAGE_LOCAL_ACCOUNTS", "ohos.permission.ACCESS_SERVICE_DM", - "ohos.permission.PROXY_AUTHORIZATION_URI" + "ohos.permission.PROXY_AUTHORIZATION_URI", + "ohos.permission.CLOUDFILE_SYNC" ] } ] 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 5c317362..04a931c9 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -24,6 +24,7 @@ #include "bootstrap.h" #include "checker/checker_manager.h" #include "communication_provider.h" +#include "communicator_context.h" #include "config_factory.h" #include "crypto_manager.h" #include "device_manager_adapter.h" @@ -101,6 +102,7 @@ void KvStoreDataService::Initialize() #ifndef UT_TEST KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default"); #endif + CommunicatorContext::getInstance().SetThreadPool(executors_); auto communicator = std::make_shared(RouteHeadHandlerImpl::Create); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); @@ -659,6 +661,17 @@ void KvStoreDataService::OnDeviceOnline(const AppDistributedKv::DeviceInfo &info }); } +void KvStoreDataService::OnDeviceOffline(const AppDistributedKv::DeviceInfo &info) +{ + if (info.uuid.empty()) { + return; + } + features_.ForEachCopies([&info](const auto &key, sptr &value) { + value->Offline(info.uuid); + return false; + }); +} + void KvStoreDataService::OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info) { if (info.uuid.empty()) { 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 4a16d21c..12f949b2 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -71,6 +71,8 @@ public: void OnDeviceOnline(const AppDistributedKv::DeviceInfo &info); + void OnDeviceOffline(const AppDistributedKv::DeviceInfo &info); + void OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info); int32_t OnUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId); diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp index 4d155a17..be0e9a79 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp @@ -26,6 +26,8 @@ void KvStoreDeviceListener::OnDeviceChanged( if (type == AppDistributedKv::DeviceChangeType::DEVICE_ONLINE) { kvStoreDataService_.SetCompatibleIdentify(info); kvStoreDataService_.OnDeviceOnline(info); + } else if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + kvStoreDataService_.OnDeviceOffline(info); } else if (type == AppDistributedKv::DeviceChangeType::DEVICE_ONREADY) { kvStoreDataService_.OnDeviceOnReady(info); } diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 95a972ff..867ca9da 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -129,7 +129,7 @@ void KvStoreMetaManager::InitDeviceOnline() ZLOGW("meta online sync error 0x%{public}08x device:%{public}s %{public}d", mask, Anonymous::Change(deviceId).c_str(), status); } - onComplete({}); + onComplete({ }); }); } @@ -361,6 +361,9 @@ void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges(CHANGE_FLAG flag, void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const { + if (info.uuid == DmAdapter::CLOUD_DEVICE_UUID) { + return; + } EventCenter::Defer defer; switch (type) { case AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE: @@ -397,6 +400,7 @@ size_t KvStoreMetaManager::GetSyncDataSize(const std::string &deviceId) return metaDelegate->GetSyncDataSize(deviceId); } + void KvStoreMetaManager::BindExecutor(std::shared_ptr executors) { executors_ = executors; diff --git a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp index 881217ef..ef791483 100644 --- a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp @@ -141,6 +141,11 @@ void Security::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, return; } + if (info.uuid == DistributedData::DeviceManagerAdapter::CLOUD_DEVICE_UUID) { + ZLOGD("This is network change"); + return; + } + bool isOnline = type == AppDistributedKv::DeviceChangeType::DEVICE_ONLINE; if (isOnline) { (void)GetSensitiveByUuid(info.uuid); @@ -161,8 +166,8 @@ Sensitive Security::GetSensitiveByUuid(const std::string &uuid) const auto it = devicesUdid_.Find(uuid); if (!it.first) { executors_->Execute([this, uuid]() { - auto it = devicesUdid_.Find(uuid); - if (it.first) { + auto iter = devicesUdid_.Find(uuid); + if (iter.first) { return; } auto udid = DistributedData::DeviceManagerAdapter::GetInstance().ToUDID(uuid); diff --git a/datamgr_service/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/datamgr_service/services/distributeddataservice/app/src/uninstaller/BUILD.gn index 54196c83..aa9913b8 100644 --- a/datamgr_service/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -35,7 +35,6 @@ ohos_static_library("distributeddata_uninstaller_static") { cflags_cc = [ "-fvisibility=hidden" ] deps = [ - "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", @@ -49,6 +48,7 @@ ohos_static_library("distributeddata_uninstaller_static") { "dataclassification:data_transit_mgr", "hilog:libhilog", "ipc:ipc_core", + "kv_store:distributeddb", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt index a9cab86e..7b569a46 100644 --- a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt @@ -29,5 +29,5 @@ include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) set(links secure mock crypto) set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/../../../../") -add_library(svcFwk SHARED ${svcFwkSrc} metadata/matrix_meta_data.cpp include/metadata/matrix_meta_data.h) +add_library(svcFwk SHARED ${svcFwkSrc}) target_link_libraries(svcFwk ${links}) 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 56fc4a8f..956478a6 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h +++ b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h @@ -19,6 +19,12 @@ namespace OHOS::DistributedData { enum GeneralError : int32_t { E_OK = 0, E_ERROR, + E_PARTIAL_ERROR, + E_NETWORK_ERROR, + E_CLOUD_DISABLED, + E_LOCKED_BY_OTHERS, + E_RECODE_LIMIT_EXCEEDED, + E_NO_SPACE_FOR_ASSET, E_BUSY, E_INVALID_ARGS, E_NOT_INIT, @@ -27,7 +33,6 @@ enum GeneralError : int32_t { E_ALREADY_CLOSED, E_UNOPENED, E_RETRY_TIMEOUT, - E_ALREADY_LOCKED, E_BUTT, }; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/cursor.h b/datamgr_service/services/distributeddataservice/framework/include/store/cursor.h index a631122e..a2693521 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/cursor.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/cursor.h @@ -37,6 +37,8 @@ public: virtual int32_t MoveToNext() = 0; + virtual int32_t MoveToPrev() = 0; + virtual int32_t GetEntry(VBucket &entry) = 0; virtual int32_t GetRow(VBucket &data) = 0; 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 0da33a6e..c7f78e9a 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -48,6 +48,7 @@ public: CLOUD_DATA, CLOUD_INFO, LOCAL_DATA, + CLEAN_MODE_BUTT }; struct BindInfo { @@ -85,6 +86,12 @@ public: virtual int32_t Unwatch(int32_t origin, Watcher &watcher) = 0; virtual int32_t Close() = 0; + + virtual int32_t AddRef() = 0; + + virtual int32_t Release() = 0; + + virtual int32_t SetDistributedTables(const std::vector &tables, int type) = 0; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp index 381c9cb7..53fb2197 100644 --- a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp @@ -161,6 +161,7 @@ AutoCache::Delegate::~Delegate() if (store_ != nullptr) { store_->Unwatch(Origin::ORIGIN_ALL, *this); store_->Close(); + store_->Release(); store_ = nullptr; } } @@ -168,7 +169,11 @@ AutoCache::Delegate::~Delegate() AutoCache::Delegate::operator Store() { time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); - return Store(store_, [](GeneralStore *) {}); + if (store_ != nullptr) { + store_->AddRef(); + return Store(store_, [](GeneralStore *store) { store->Release(); }); + } + return nullptr; } bool AutoCache::Delegate::operator<(const AutoCache::Time &time) const @@ -185,7 +190,6 @@ bool AutoCache::Delegate::Close() if (status == Error::E_BUSY) { return false; } - store_ = nullptr; } return true; } diff --git a/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp index 697b33b5..3729a6e4 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/serializable_test.cpp @@ -198,6 +198,7 @@ HWTEST_F(SerializableTest, GetMapInStruct, TestSize.Level2) ~TestMeta() { delete index; + index = nullptr; } bool Marshal(json &node) const { diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index 42b0e4b6..023498d5 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -100,29 +100,25 @@ ohos_shared_library("distributeddatasvc") { "rdb/rdb_result_set_stub.cpp", "rdb/rdb_service_impl.cpp", "rdb/rdb_service_stub.cpp", - "rdb/rdb_store_observer_impl.cpp", - "rdb/rdb_syncer.cpp", "rdb/rdb_watcher.cpp", "rdb/value_proxy.cpp", ] - cflags = [ "-Wno-multichar" ] + cflags = [ + "-Wno-multichar", + "-Wno-c99-designator", + ] cflags_cc = [ "-fvisibility=hidden" ] configs = [ ":module_public_config" ] deps = [ - "${kv_store_distributeddb_path}:distributeddb", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", ] external_deps = [ - "ability_base:want", - "ability_base:zuri", - "ability_runtime:ability_manager", - "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", @@ -132,6 +128,7 @@ ohos_shared_library("distributeddatasvc") { "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", + "kv_store:distributeddb", "relational_store:native_rdb", ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt index c3b35f45..310a7518 100644 --- a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt @@ -71,6 +71,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../adapter/include/permission) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../adapter/include/security) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../adapter/include/utils) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../app/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../kv_store/frameworks/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../relational_store/interfaces/inner_api/appdatafwk/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../relational_store/interfaces/inner_api/cloud_data/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../relational_store/interfaces/inner_api/rdb/include) 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 844f2ed3..65ba0305 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -21,6 +21,7 @@ #include "checker/checker_manager.h" #include "cloud/cloud_server.h" #include "communicator/device_manager_adapter.h" +#include "device_manager_adapter.h" #include "eventcenter/event_center.h" #include "ipc_skeleton.h" #include "log_print.h" @@ -28,6 +29,7 @@ #include "rdb_cloud_data_translate.h" #include "runtime_config.h" #include "store/auto_cache.h" +#include "store/general_store.h" #include "utils/anonymous.h" #include "sync_manager.h" namespace OHOS::CloudData { @@ -37,11 +39,6 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Account = OHOS::DistributedKv::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; __attribute__((used)) CloudServiceImpl::Factory CloudServiceImpl::factory_; -const CloudServiceImpl::Work CloudServiceImpl::HANDLERS[WORK_BUTT] = { - &CloudServiceImpl::DoSubscribe, - &CloudServiceImpl::UpdateCloudInfo, - &CloudServiceImpl::UpdateSchema, -}; CloudServiceImpl::Factory::Factory() noexcept { @@ -82,7 +79,7 @@ int32_t CloudServiceImpl::EnableCloud(const std::string &id, const std::map()); - Execute(GetCloudTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + Execute(GenTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB })); return E_OK; } @@ -233,12 +230,45 @@ int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, c { int32_t userId = atoi(user.c_str()); if (code == static_cast(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) { - Execute(GetCloudTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + Execute(GenTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB })); } syncManager_.StopCloudSync(userId); return E_OK; } +int32_t CloudServiceImpl::Online(const std::string &device) +{ + if (device != DeviceManagerAdapter::CLOUD_DEVICE_UUID) { + ZLOGI("Not network online"); + return SUCCESS; + } + std::vector users; + Account::GetInstance()->QueryUsers(users); + if (users.empty()) { + return SUCCESS; + } + auto it = users.begin(); + syncManager_.DoCloudSync({ *it }); + Execute(GenTask(0, *it, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB })); + return SUCCESS; +} + +int32_t CloudServiceImpl::Offline(const std::string &device) +{ + if (device != DeviceManagerAdapter::CLOUD_DEVICE_UUID) { + ZLOGI("Not network offline"); + return SUCCESS; + } + std::vector users; + Account::GetInstance()->QueryUsers(users); + if (users.empty()) { + return SUCCESS; + } + auto it = users.begin(); + syncManager_.StopCloudSync(*it); + return SUCCESS; +} + int32_t CloudServiceImpl::GetCloudInfo(uint32_t tokenId, const std::string &id, CloudInfo &cloudInfo) { cloudInfo.user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); @@ -298,7 +328,7 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user) Anonymous::Change(oldInfo.id).c_str()); std::map actions; for (auto &[bundle, app] : cloudInfo.apps) { - actions[bundle] = CLEAR_CLOUD_INFO; + actions[bundle] = GeneralStore::CleanMode::CLOUD_INFO; } DoClean(oldInfo, actions); } @@ -345,40 +375,36 @@ int32_t CloudServiceImpl::GetAppSchema(int32_t user, const std::string &bundleNa return SUCCESS; } -CloudServiceImpl::Tasks CloudServiceImpl::GetCloudTask( - int32_t retry, int32_t user, const std::initializer_list &works) -{ - Tasks tasks; - tasks.reserve(works.size() + 1); - for (auto work : works) { - tasks.push_back(GenTask(retry, user, work)); - } - tasks.push_back(GenTask(retry, user, WORK_SUB)); - return tasks; -} - -ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, AsyncWork work) +ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, Handles handles) { - return [this, retry, user, work]() -> void { + return [this, retry, user, works = std::move(handles)]() mutable { auto executor = executor_; - if (retry >= RETRY_TIMES || executor == nullptr) { + if (retry >= RETRY_TIMES || executor == nullptr || works.empty()) { + return; + } + if (!DmAdapter::GetInstance().IsNetworkAvailable()) { return; } - bool finished = true; std::vector users; if (user == 0) { auto account = Account::GetInstance(); - finished = account == nullptr ? false : account->QueryUsers(users); + finished = !(account == nullptr) && account->QueryUsers(users); } else { users.push_back(user); } + auto handle = works.front(); for (auto user : users) { - finished = (this->*HANDLERS[work])(user) && finished; + finished = (this->*handle)(user) && finished; } - if (!finished) { - executor->Schedule(std::chrono::seconds(RETRY_INTERVAL), GenTask(retry + 1, user, work)); + if (!finished || users.empty()) { + executor->Schedule(std::chrono::seconds(RETRY_INTERVAL), GenTask(retry + 1, user, std::move(works))); + return; + } + works.pop_front(); + if (!works.empty()) { + executor->Execute(GenTask(retry, user, std::move(works))); } }; } @@ -441,6 +467,7 @@ int32_t CloudServiceImpl::OnAppUninstall( (void)tokenId; MetaDataManager::GetInstance().DelMeta(Subscription::GetRelationKey(user, bundleName), true); MetaDataManager::GetInstance().DelMeta(CloudInfo::GetSchemaKey(user, bundleName, index), true); + AutoCache::GetInstance().CloseStore(tokenId); return E_OK; } @@ -506,14 +533,12 @@ bool CloudServiceImpl::DoSubscribe(int32_t user) return subDbs.empty() && unsubDbs.empty(); } -void CloudServiceImpl::Execute(Tasks tasks) +void CloudServiceImpl::Execute(Task task) { - for (auto &task : tasks) { - auto executor = executor_; - if (executor == nullptr) { - return; - } - executor->Execute(std::move(task)); + auto executor = executor_; + if (executor == nullptr) { + return; } + executor->Execute(std::move(task)); } } // namespace OHOS::CloudData \ No newline at end of file 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 31599142..b2ed723a 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -17,6 +17,7 @@ #define OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_SERVICE_IMPL_H #include +#include #include "cloud/cloud_event.h" #include "cloud/cloud_info.h" #include "cloud/schema_meta.h" @@ -38,6 +39,8 @@ public: int32_t OnBind(const BindInfo &info) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; + int32_t Online(const std::string &device) override; + int32_t Offline(const std::string &device) override; private: class Factory { @@ -53,19 +56,13 @@ private: using SchemaMeta = DistributedData::SchemaMeta; using Event = DistributedData::Event; using Subscription = DistributedData::Subscription; - using Work = bool (CloudServiceImpl::*)(int32_t); - using Tasks = std::vector; + using Handle = bool (CloudServiceImpl::*)(int32_t); + using Handles = std::deque; + using Task = ExecutorPool::Task; - enum AsyncWork : int32_t { - WORK_SUB = 0, - WORK_CLOUD_INFO_UPDATE, - WORK_SCHEMA_UPDATE, - WORK_BUTT, - }; - - static constexpr int32_t RETRY_TIMES = 10; - static constexpr int32_t RETRY_INTERVAL = 30; - static constexpr int32_t EXPIRE_INTERVAL = 7 * 24; // 7 day + static constexpr int32_t RETRY_TIMES = 3; + static constexpr int32_t RETRY_INTERVAL = 60; + static constexpr int32_t EXPIRE_INTERVAL = 2 * 24; // 2 day bool UpdateCloudInfo(int32_t user); bool UpdateSchema(int32_t user); @@ -76,14 +73,16 @@ private: int32_t GetCloudInfoFromServer(CloudInfo &cloudInfo); int32_t GetAppSchema(int32_t user, const std::string &bundleName, SchemaMeta &schemaMeta); void GetSchema(const Event &event); - Tasks GetCloudTask(int32_t retry, int32_t user, const std::initializer_list &works = {}); - ExecutorPool::Task GenTask(int32_t retry, int32_t user, AsyncWork work); - void Execute(Tasks tasks); + Task GenTask(int32_t retry, int32_t user, Handles handles = { WORK_SUB }); + void Execute(Task task); bool DoSubscribe(int32_t user); int32_t DoClean(CloudInfo &cloudInfo, const std::map &actions); std::shared_ptr executor_; SyncManager syncManager_; - static const Work HANDLERS[WORK_BUTT]; + + static constexpr Handle WORK_CLOUD_INFO_UPDATE = &CloudServiceImpl::UpdateCloudInfo; + static constexpr Handle WORK_SCHEMA_UPDATE = &CloudServiceImpl::UpdateSchema; + static constexpr Handle WORK_SUB = &CloudServiceImpl::DoSubscribe; }; } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index 8bc0025d..8cf44724 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -172,21 +172,26 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount CloudInfo cloud; cloud.user = info.user_; if (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true)) { - info.SetError(E_NOT_INIT); + info.SetError(E_CLOUD_DISABLED); ZLOGE("no cloud info for user:%{public}d", info.user_); return; } if (!cloud.enableCloud || (info.id_ != SyncInfo::DEFAULT_ID && cloud.id != info.id_) || (!info.bundleName_.empty() && !cloud.IsOn(info.bundleName_))) { - info.SetError(E_UNOPENED); + info.SetError(E_CLOUD_DISABLED); + return; + } + + if (!DmAdapter::GetInstance().IsNetworkAvailable()) { + info.SetError(E_NETWORK_ERROR); return; } std::vector schemas; auto key = cloud.GetSchemaPrefix(info.bundleName_); auto retryer = GetRetryer(times, info); - if (!MetaDataManager::GetInstance().LoadMeta(key, schemas, true)) { + if (!MetaDataManager::GetInstance().LoadMeta(key, schemas, true) || schemas.empty()) { UpdateSchema(info); retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT); return; @@ -244,7 +249,7 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) return; } int32_t code = details.begin()->second.code; - retryer(code == E_ALREADY_LOCKED ? LOCKED_INTERVAL : RETRY_INTERVAL, code); + retryer(code == E_LOCKED_BY_OTHERS ? LOCKED_INTERVAL : RETRY_INTERVAL, code); } : evt.GetAsyncDetail(), evt.GetWait()); GenAsync async = evt.GetAsyncDetail(); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn index 8cb08cb8..705e41f2 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn @@ -36,10 +36,12 @@ group("build_module") { ohos_shared_library("data_share_service") { sources = [ "common/app_connect_manager.cpp", + "common/base64_utils.cpp", "common/bundle_mgr_proxy.cpp", "common/db_delegate.cpp", "common/div_strategy.cpp", "common/extension_connect_adaptor.cpp", + "common/extension_mgr_proxy.cpp", "common/kv_delegate.cpp", "common/rdb_delegate.cpp", "common/scheduler_manager.cpp", @@ -91,13 +93,14 @@ ohos_shared_library("data_share_service") { external_deps = [ "ability_base:want", "ability_base:zuri", - "ability_runtime:ability_manager", "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", + "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "device_manager:devicemanagersdk", "hilog:libhilog", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.cpp new file mode 100644 index 00000000..f51f9268 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base64_utils.h" + +#include +#include + +namespace OHOS::DataShare::Base64 { +static constexpr const std::string_view BASE64_CHARS = /* NOLINT */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static constexpr const uint32_t CHAR_ARRAY_LENGTH_THREE = 3; +static constexpr const uint32_t CHAR_ARRAY_LENGTH_FOUR = 4; + +enum BASE64_ENCODE_CONSTANT : uint8_t { + BASE64_ENCODE_MASK1 = 0xfc, + BASE64_ENCODE_MASK2 = 0x03, + BASE64_ENCODE_MASK3 = 0x0f, + BASE64_ENCODE_MASK4 = 0x3f, + BASE64_ENCODE_MASK5 = 0xf0, + BASE64_ENCODE_MASK6 = 0xc0, + BASE64_ENCODE_OFFSET2 = 2, + BASE64_ENCODE_OFFSET4 = 4, + BASE64_ENCODE_OFFSET6 = 6, + BASE64_ENCODE_INDEX0 = 0, + BASE64_ENCODE_INDEX1 = 1, + BASE64_ENCODE_INDEX2 = 2, +}; + +enum BASE64_DECODE_CONSTANT : uint8_t { + BASE64_DECODE_MASK1 = 0x30, + BASE64_DECODE_MASK2 = 0xf, + BASE64_DECODE_MASK3 = 0x3c, + BASE64_DECODE_MASK4 = 0x3, + BASE64_DECODE_OFFSET2 = 2, + BASE64_DECODE_OFFSET4 = 4, + BASE64_DECODE_OFFSET6 = 6, + BASE64_DECODE_INDEX0 = 0, + BASE64_DECODE_INDEX1 = 1, + BASE64_DECODE_INDEX2 = 2, + BASE64_DECODE_INDEX3 = 3, +}; + +static inline bool IsBase64Char(const char c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} + +static void MakeCharFour(const std::array &charArrayThree, + std::array &charArrayFour) +{ + const uint8_t table[CHAR_ARRAY_LENGTH_FOUR] = { + static_cast((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK1) >> BASE64_ENCODE_OFFSET2), + static_cast(((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK2) << BASE64_ENCODE_OFFSET4) + + ((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK5) >> BASE64_ENCODE_OFFSET4)), + static_cast(((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK3) << BASE64_ENCODE_OFFSET2) + + ((charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK6) >> BASE64_ENCODE_OFFSET6)), + static_cast(charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK4), + }; + for (size_t index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { + charArrayFour[index] = table[index]; + } +} + +static void MakeCharTree(const std::array &charArrayFour, + std::array &charArrayThree) +{ + const uint8_t table[CHAR_ARRAY_LENGTH_THREE] = { + static_cast((charArrayFour[BASE64_DECODE_INDEX0] << BASE64_DECODE_OFFSET2) + + ((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK1) >> BASE64_DECODE_OFFSET4)), + static_cast(((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK2) << BASE64_DECODE_OFFSET4) + + ((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK3) >> BASE64_DECODE_OFFSET2)), + static_cast(((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK4) << BASE64_DECODE_OFFSET6) + + charArrayFour[BASE64_DECODE_INDEX3]), + }; + for (size_t index = 0; index < CHAR_ARRAY_LENGTH_THREE; ++index) { + charArrayThree[index] = table[index]; + } +} + +std::string Encode(const std::vector &source) +{ + auto it = source.begin(); + std::string ret; + size_t index = 0; + std::array charArrayThree = { 0 }; + std::array charArrayFour = { 0 }; + + while (it != source.end()) { + charArrayThree[index] = *it; + ++index; + ++it; + if (index != CHAR_ARRAY_LENGTH_THREE) { + continue; + } + MakeCharFour(charArrayThree, charArrayFour); + std::for_each(charArrayFour.begin(), charArrayFour.end(), [&ret](uint8_t idx) { + ret += BASE64_CHARS[idx]; + }); + index = 0; + } + if (index == 0) { + return ret; + } + + for (auto i = index; i < CHAR_ARRAY_LENGTH_THREE; ++i) { + charArrayThree[i] = 0; + } + MakeCharFour(charArrayThree, charArrayFour); + + for (size_t i = 0; i < index + 1; ++i) { + ret += BASE64_CHARS[charArrayFour[i]]; + } + + while (index < CHAR_ARRAY_LENGTH_THREE) { + ret += '='; + ++index; + } + return ret; +} + +std::vector Decode(const std::string &encoded) +{ + auto it = encoded.begin(); + size_t index = 0; + std::array charArrayThree = { 0 }; + std::array charArrayFour = { 0 }; + std::vector ret; + + while (it != encoded.end() && IsBase64Char(*it)) { + charArrayFour[index] = *it; + ++index; + ++it; + if (index != CHAR_ARRAY_LENGTH_FOUR) { + continue; + } + for (index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { + charArrayFour[index] = BASE64_CHARS.find(static_cast(charArrayFour[index])); + } + MakeCharTree(charArrayFour, charArrayThree); + std::for_each(charArrayThree.begin(), charArrayThree.end(), [&ret](uint8_t idx) { + ret.emplace_back(idx); + }); + index = 0; + } + if (index == 0) { + return ret; + } + + for (auto i = index; i < CHAR_ARRAY_LENGTH_FOUR; ++i) { + charArrayFour[i] = 0; + } + for (unsigned char &i : charArrayFour) { + std::string::size_type idx = BASE64_CHARS.find(static_cast(i)); + if (idx != std::string::npos) { + i = static_cast(idx); + } + } + MakeCharTree(charArrayFour, charArrayThree); + + for (size_t i = 0; i < index - 1; i++) { + ret.emplace_back(charArrayThree[i]); + } + return ret; +} +} // namespace OHOS::DataShare::Base64 diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.h similarity index 49% rename from datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp rename to datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.h index e9e7ec53..4593bd0e 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/base64_utils.h @@ -13,29 +13,15 @@ * limitations under the License. */ -#define LOG_TAG "RdbStoreObserverImpl" +#ifndef DATASHARESERVICE_BASE64_H +#define DATASHARESERVICE_BASE64_H -#include "rdb_store_observer_impl.h" -#include "rdb_service_impl.h" -#include "log_print.h" +#include +#include -namespace OHOS::DistributedRdb { -RdbStoreObserverImpl::RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid, uint32_t tokenId) - : pid_(pid), tokenId_(tokenId), owner_(owner) -{ - ZLOGI("construct"); -} +namespace OHOS::DataShare::Base64 { +std::string Encode(const std::vector &source); +std::vector Decode(const std::string &encoded); +} // namespace OHOS::DataShare::Base64 -RdbStoreObserverImpl::~RdbStoreObserverImpl() -{ - ZLOGI("destroy"); -} - -void RdbStoreObserverImpl::OnChange(const DistributedDB::StoreChangedData &data) -{ - ZLOGI("enter"); - if (owner_ != nullptr) { - owner_->OnDataChange(pid_, tokenId_, data); - } -} -} // namespace OHOS::DistributedRdb +#endif /* DATASHARESERVICE_BASE64_H */ diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h index 2eb22014..451f375f 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/callback_impl.h @@ -16,7 +16,6 @@ #define DATASHARESERVICE_CALLBACK_IMPL_H #include "ability_connect_callback_stub.h" -#include "ability_manager_client.h" #include "block_data.h" namespace OHOS::DataShare { 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 caad0114..2424abf2 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 @@ -20,6 +20,7 @@ #include "app_connect_manager.h" #include "callback_impl.h" +#include "extension_mgr_proxy.h" #include "log_print.h" namespace OHOS::DataShare { @@ -37,8 +38,6 @@ ExtensionConnectAdaptor::ExtensionConnectAdaptor() : data_(1) {} bool ExtensionConnectAdaptor::DoConnect(std::shared_ptr context) { - AAFwk::Want want; - want.SetUri(context->uri); data_.Clear(); callback_ = new (std::nothrow) CallbackImpl(data_); if (callback_ == nullptr) { @@ -46,7 +45,7 @@ bool ExtensionConnectAdaptor::DoConnect(std::shared_ptr context) return false; } ZLOGI("Start connect %{public}s", context->uri.c_str()); - ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, callback_, nullptr); + ErrCode ret = ExtensionMgrProxy::GetInstance()->Connect(context->uri, callback_->AsObject(), nullptr); if (ret != ERR_OK) { ZLOGE("connect ability failed, ret = %{public}d", ret); return false; @@ -80,7 +79,7 @@ void ExtensionConnectAdaptor::Disconnect() } data_.Clear(); ZLOGI("Start disconnect"); - AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(callback_); + ExtensionMgrProxy::GetInstance()->DisConnect(callback_->AsObject()); if (!data_.GetValue()) { ZLOGI("disconnect ability ended successfully"); } 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 new file mode 100644 index 00000000..3303346e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AppConnectManager" +#include "extension_mgr_proxy.h" + +#include "app_connect_manager.h" +#include "extension_ability_info.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "log_print.h" +#include "system_ability_definition.h" +#include "want.h" +namespace OHOS::DataShare { +void ExtensionMgrProxy::OnProxyDied() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; + proxy_ = nullptr; +} + +ExtensionMgrProxy::~ExtensionMgrProxy() +{ + std::lock_guard lock(mutex_); + if (sa_ != nullptr) { + sa_->RemoveDeathRecipient(deathRecipient_); + } +} + +std::shared_ptr ExtensionMgrProxy::GetInstance() +{ + static std::shared_ptr proxy = std::make_shared(); + return proxy; +} + +int ExtensionMgrProxy::Connect( + const std::string &uri, const sptr &connect, const sptr &callerToken) +{ + AAFwk::Want want; + want.SetUri(uri); + std::lock_guard lock(mutex_); + if (ConnectSA()) { + int ret = proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); + if (ret != ERR_OK) { + ZLOGE("ConnectAbilityCommon failed, %{public}d", ret); + } + return ret; + } + return -1; +} + +bool ExtensionMgrProxy::ConnectSA() +{ + if (proxy_ != nullptr) { + return true; + } + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + ZLOGE("Failed to get system ability mgr."); + return false; + } + + sa_ = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (sa_ == nullptr) { + ZLOGE("Failed to GetSystemAbility."); + return false; + } + deathRecipient_ = new (std::nothrow) ExtensionMgrProxy::ServiceDeathRecipient(weak_from_this()); + if (deathRecipient_ == nullptr) { + ZLOGE("deathRecipient alloc failed."); + return false; + } + sa_->AddDeathRecipient(deathRecipient_); + proxy_ = new (std::nothrow)Proxy(sa_); + if (proxy_ == nullptr) { + ZLOGE("proxy_ null, new failed"); + return false; + } + return true; +} + +int ExtensionMgrProxy::DisConnect(sptr connect) +{ + std::lock_guard lock(mutex_); + if (ConnectSA()) { + int ret = proxy_->DisconnectAbility(connect); + if (ret != ERR_OK) { + ZLOGE("DisconnectAbility failed, %{public}d", ret); + } + return ret; + } + return -1; +} +} // namespace OHOS::DataShare \ No newline at end of file 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 new file mode 100644 index 00000000..a93a4c90 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_mgr_proxy.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARESERVICE_EXTENSION_PROXY_H +#define DATASHARESERVICE_EXTENSION_PROXY_H + +#include +#include + +#include "extension_manager_proxy.h" +namespace OHOS::DataShare { +class ExtensionMgrProxy final : public std::enable_shared_from_this { +public: + // do not use + ExtensionMgrProxy() = default; + ~ExtensionMgrProxy(); + static std::shared_ptr GetInstance(); + int Connect(const std::string &uri, const sptr &connect, const sptr &callerToken); + int DisConnect(sptr connect); +private: + using Proxy = AAFwk::ExtensionManagerProxy; + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit ServiceDeathRecipient(std::weak_ptr owner) : owner_(owner) + { + } + void OnRemoteDied(const wptr &object) override + { + auto owner = owner_.lock(); + if (owner != nullptr) { + owner->OnProxyDied(); + } + } + + private: + std::weak_ptr owner_; + }; + void OnProxyDied(); + bool ConnectSA(); + std::mutex mutex_; + sptr sa_; + sptr proxy_; + sptr deathRecipient_; +}; +} // namespace OHOS::DataShare +#endif // DATASHARESERVICE_BUNDLEMGR_PROXY_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp index c0c96fc1..5b0cfde9 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp @@ -39,9 +39,6 @@ void SchedulerManager::Execute(const std::string &uri, const int32_t userId, con } std::vector keys = RdbSubscriberManager::GetInstance().GetKeysByUri(uri); for (auto const &key : keys) { - if (RdbSubscriberManager::GetInstance().GetCount(key) == 0) { - continue; - } ExecuteSchedulerSQL(rdbDir, userId, version, key, delegate); } } @@ -64,23 +61,33 @@ void SchedulerManager::SetTimer( ZLOGE("executor_ is nullptr"); return; } + int64_t now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + // reminder time must is in future + if (reminderTime <= now) { + ZLOGE("reminderTime is not in future, %{public}" PRId64 "%{public}" PRId64, reminderTime, now); + return; + } + auto duration = std::chrono::milliseconds(reminderTime - now); + ZLOGI("reminderTime will notify in %{public}" PRId64 " milliseconds", reminderTime - now); auto it = timerCache_.find(key); if (it != timerCache_.end()) { // has current timer, reset time - ZLOGD("has current taskId, uri is %{public}s, subscriberId is %{public}" PRId64 ", bundleName is %{public}s", - DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); - executor_->Reset(it->second, std::chrono::seconds(reminderTime - time(nullptr))); + ZLOGD("has current taskId, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is %{public}s", + key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + executor_->Reset(it->second, duration); return; } // not find task in map, create new timer - auto taskId = executor_->Schedule(std::chrono::seconds(reminderTime - time(nullptr)), - [key, dbPath, version, userId, this]() { - timerCache_.erase(key); - // 1. execute schedulerSQL in next time - Execute(key, userId, dbPath, version); - // 2. notify - RdbSubscriberManager::GetInstance().EmitByKey(key, userId, dbPath, version); - }); + auto taskId = executor_->Schedule(duration, [key, dbPath, version, userId, this]() { + ZLOGI("schedule notify start, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is " + "%{public}s", key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + timerCache_.erase(key); + // 1. execute schedulerSQL in next time + Execute(key, userId, dbPath, version); + // 2. notify + RdbSubscriberManager::GetInstance().EmitByKey(key, userId, dbPath, version); + }); if (taskId == ExecutorPool::INVALID_TASK_ID) { ZLOGE("create timer failed, over the max capacity"); return; @@ -152,7 +159,7 @@ void SchedulerManager::RemoveTimer(const Key &key) } auto it = timerCache_.find(key); if (it != timerCache_.end()) { - ZLOGD("RemoveTimer %{public}s %{public}s %{public}" PRId64, + ZLOGW("RemoveTimer %{public}s %{public}s %{public}" PRId64, DistributedData::Anonymous::Change(key.uri).c_str(), key.bundleName.c_str(), key.subscriberId); executor_->Remove(it->second); timerCache_.erase(key); @@ -178,5 +185,14 @@ void SchedulerManager::SetExecutorPool(std::shared_ptr executor) { executor_ = executor; } + +void SchedulerManager::ReExecuteAll() +{ + std::lock_guard lock(mutex_); + for (auto &item : timerCache_) { + // restart in 200ms + executor_->Reset(item.second, std::chrono::milliseconds(200)); + } +} } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h index d133218a..939da970 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h @@ -28,6 +28,7 @@ public: static SchedulerManager &GetInstance(); void Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version); void Execute(const Key &key, const int32_t userId, const std::string &rdbDir, int version); + void ReExecuteAll(); void SetTimer(const std::string &dbPath, const int32_t userId, int version, const Key &key, int64_t reminderTime); void RemoveTimer(const Key &key); void ClearTimer(); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.cpp index 416b27c9..2ae1231d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.cpp @@ -17,6 +17,7 @@ #include "log_print.h" #include "subscriber_managers/published_data_subscriber_manager.h" +#include "base64_utils.h" namespace OHOS::DataShare { bool PublishedData::HasVersion() const @@ -106,6 +107,35 @@ PublishedDataNode::PublishedDataNode(const std::string &key, const std::string & PublishedDataNode::PublishedDataNode() : VersionData(-1) {} +std::variant, std::string> PublishedDataNode::MoveTo(const PublishedDataNode::Data &data) +{ + auto *valueStr = std::get_if(&data); + if (valueStr != nullptr) { + return *valueStr; + } + auto *valueBytes = std::get_if(&data); + if (valueBytes != nullptr) { + return Base64::Decode(valueBytes->data); + } + ZLOGE("error"); + return ""; +} + +PublishedDataNode::Data PublishedDataNode::MoveTo(std::variant, std::string> &data) +{ + auto *valueStr = std::get_if(&data); + if (valueStr != nullptr) { + return *valueStr; + } + auto *valueBytes = std::get_if>(&data); + if (valueBytes != nullptr) { + std::string valueEncode = Base64::Encode(*valueBytes); + return BytesData(std::move(valueEncode)); + } + ZLOGE("error"); + return ""; +} + int32_t PublishedData::Query(const std::string &filter, PublishedDataNode::Data &publishedData) { auto delegate = KvDBDelegate::GetInstance(); @@ -224,4 +254,19 @@ void PublishedData::UpdateTimestamp( ZLOGI("update timestamp %{private}s", data.key.c_str()); } } + +PublishedDataNode::BytesData::BytesData(std::string &&data) : data(std::move(data)) +{ +} + +bool PublishedDataNode::BytesData::Marshal(DistributedData::Serializable::json &node) const +{ + return SetValue(node[GET_NAME(data)], data); +} + +bool PublishedDataNode::BytesData::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(data), data); + return ret; +} } // namespace OHOS::DataShare \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.h b/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.h index cff038a3..e1d45003 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/published_data.h @@ -22,7 +22,16 @@ namespace OHOS::DataShare { class PublishedDataNode final : public VersionData { public: - using Data = std::variant, std::string>; + struct BytesData : public DistributedData::Serializable { + explicit BytesData(std::string &&data); + BytesData() = default; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + std::string data; + }; + using Data = std::variant; + static std::variant, std::string> MoveTo(const Data &data); + static Data MoveTo(std::variant, std::string> &data); PublishedDataNode(); PublishedDataNode(const std::string &key, const std::string &bundleName, int64_t subscriberId, const int32_t userId, const Data &value); @@ -31,7 +40,7 @@ public: bool Unmarshal(const json &node) override; std::string key; std::string bundleName; - int64_t subscriberId; + int64_t subscriberId = 0; Data value; int32_t userId = Id::INVALID_USER; std::time_t timestamp = 0; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp index 04e2d908..5bdfa4a7 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/resultset_json_formatter.cpp @@ -21,6 +21,7 @@ namespace OHOS::DataShare { bool ResultSetJsonFormatter::Marshal(json &node) const { + node = json::array(); int columnCount = 0; auto result = resultSet->GetColumnCount(columnCount); if (result != NativeRdb::E_OK) { 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 568c1046..7ac7378b 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 @@ -20,6 +20,8 @@ #include "accesstoken_kit.h" #include "account/account_delegate.h" #include "app_connect_manager.h" +#include "common_event_manager.h" +#include "common_event_support.h" #include "dataobs_mgr_client.h" #include "datashare_errno.h" #include "datashare_template.h" @@ -27,10 +29,11 @@ #include "hap_token_info.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "matching_skills.h" #include "scheduler_manager.h" #include "subscriber_managers/published_data_subscriber_manager.h" -#include "utils/anonymous.h" #include "template_data.h" +#include "utils/anonymous.h" namespace OHOS::DataShare { using FeatureSystem = DistributedData::FeatureSystem; @@ -52,8 +55,6 @@ int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValu if (ret) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, context); - SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version); } return ret; } @@ -83,8 +84,6 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred if (ret) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, context); - SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version); } return ret; } @@ -97,8 +96,6 @@ int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePred if (ret) { NotifyChange(uri); RdbSubscriberManager::GetInstance().Emit(uri, context); - SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version); } return ret; } @@ -123,7 +120,7 @@ int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t return templateStrategy_.Execute(context, [&uri, &tpltId, &tplt, &context]() -> int32_t { auto result = TemplateManager::GetInstance().Add( Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId, tplt); - RdbSubscriberManager::GetInstance().Emit(context->uri, context); + RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, context); return result; }); } @@ -191,6 +188,7 @@ std::vector DataShareServiceImpl::Publish(const Data &data, con } if (!publishedData.empty()) { PublishedDataSubscriberManager::GetInstance().Emit(publishedData, userId, callerBundleName); + PublishedDataSubscriberManager::GetInstance().SetObserversNotifiedOnEnabled(publishedData); } return results; } @@ -362,7 +360,10 @@ std::vector DataShareServiceImpl::EnablePubSubs(const std::vect } results.emplace_back(uri, result); if (result == E_OK) { - publishedKeys.emplace_back(context->uri, context->callerBundleName, subscriberId); + PublishedDataKey pKey(context->uri, context->callerBundleName, subscriberId); + if (PublishedDataSubscriberManager::GetInstance().IsNotifyOnEnabled(pKey, context->callerTokenId)) { + publishedKeys.emplace_back(pKey); + } userId = context->currentUserId; } } @@ -429,14 +430,7 @@ int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo) saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); KvDBDelegate::GetInstance(false, saveMeta.dataDir, binderInfo.executors); SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors); - return EOK; -} - -int32_t DataShareServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) -{ - RdbSubscriberManager::GetInstance().Clear(); - PublishedDataSubscriberManager::GetInstance().Clear(); - SchedulerManager::GetInstance().ClearTimer(); + SubscribeTimeChanged(); return EOK; } @@ -461,6 +455,15 @@ int32_t DataShareServiceImpl::OnAppUninstall( return EOK; } +int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) +{ + ZLOGI("AppExit uid=%{public}d, pid=%{public}d, tokenId=0x%{public}x, bundleName=%{public}s", + uid, pid, tokenId, bundleName.c_str()); + RdbSubscriberManager::GetInstance().Delete(tokenId); + PublishedDataSubscriberManager::GetInstance().Delete(tokenId); + return EOK; +} + void DataShareServiceImpl::NotifyObserver(const std::string &uri) { ZLOGD("%{private}s try notified", uri.c_str()); @@ -475,4 +478,36 @@ void DataShareServiceImpl::NotifyObserver(const std::string &uri) RdbSubscriberManager::GetInstance().Emit(uri, context); } } + +bool DataShareServiceImpl::SubscribeTimeChanged() +{ + ZLOGD("start"); + EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED); + EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); + subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); + timerReceiver_ = std::make_shared(subscribeInfo); + auto result = EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_); + if (!result) { + ZLOGE("SubscribeCommonEvent err"); + } + return result; +} + +void DataShareServiceImpl::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData) +{ + AAFwk::Want want = eventData.GetWant(); + std::string action = want.GetAction(); + ZLOGI("action:%{public}s.", action.c_str()); + if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED + || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) { + SchedulerManager::GetInstance().ReExecuteAll(); + } +} + +DataShareServiceImpl::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo) + : CommonEventSubscriber(subscriberInfo) +{ +} } // namespace OHOS::DataShare 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 72d102ca..4c82a69c 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 @@ -18,6 +18,8 @@ #include +#include "common_event_subscribe_info.h" +#include "common_event_subscriber.h" #include "data_proxy_observer.h" #include "data_share_service_stub.h" #include "datashare_template.h" @@ -66,8 +68,8 @@ public: const int64_t subscriberId) override; void OnConnectDone() override; int32_t OnBind(const BindInfo &binderInfo) override; - int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index, uint32_t tokenId) override; + int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) override; void NotifyObserver(const std::string &uri) override; private: @@ -76,7 +78,14 @@ private: Factory(); ~Factory(); }; - + class TimerReceiver : public EventFwk::CommonEventSubscriber { + public: + TimerReceiver() = default; + explicit TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo); + virtual ~TimerReceiver() = default; + virtual void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; + }; + bool SubscribeTimeChanged(); bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); static Factory factory_; @@ -91,6 +100,7 @@ private: TemplateStrategy templateStrategy_; RdbNotifyStrategy rdbNotifyStrategy_; BindInfo binderInfo_; + std::shared_ptr timerReceiver_ = nullptr; }; } // namespace OHOS::DataShare #endif diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn index 293099f3..3f44a373 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn @@ -59,6 +59,7 @@ ohos_shared_library("gaussdb_rd") { "src/executor/document/grd_resultset_api.cpp", "src/interface/src/collection.cpp", "src/interface/src/doc_errno.cpp", + "src/interface/src/document_key.cpp", "src/interface/src/document_store.cpp", "src/interface/src/document_store_manager.cpp", "src/interface/src/projection_tree.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h index 8f982807..6062f9fe 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h @@ -23,9 +23,6 @@ class CollectionOption final { public: static CollectionOption ReadOption(const std::string &optStr, int &errCode); - uint32_t GetMaxDoc() const; - std::string ToString() const; - bool operator==(const CollectionOption &targetOption) const; bool operator!=(const CollectionOption &targetOption) const; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h index 557b92da..fc2515f3 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h @@ -17,6 +17,6 @@ #define DOC_LIMIT_H namespace DocumentDB { -constexpr int MAX_DB_CONFIG_LEN = 512 * 1024; // 512 * 1024: 512k length +constexpr int MAX_DB_CONFIG_LEN = 1024 * 1024; // 1024 * 1024: 1024k length } // namespace DocumentDB #endif // DOC_LIMIT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h index ff525ecb..0c767b9a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h @@ -28,7 +28,7 @@ struct QueryContext { ProjectionTree projectionTree; bool ifShowId = false; bool viewType = false; - bool isOnlyId = false; + bool isIdExist = false; }; } // namespace DocumentDB #endif // DOCUMENT_TYPE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp index 324a2931..d5310f73 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp @@ -92,24 +92,4 @@ CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &er option.option_ = optStr; return option; } - -uint32_t CollectionOption::GetMaxDoc() const -{ - return maxDoc_; -} - -std::string CollectionOption::ToString() const -{ - return option_; -} - -bool CollectionOption::operator==(const CollectionOption &targetOption) const -{ - return maxDoc_ == targetOption.maxDoc_; -} - -bool CollectionOption::operator!=(const CollectionOption &targetOption) const -{ - return !(*this == targetOption); -} } // namespace DocumentDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp index 44ce39b6..5061139e 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp @@ -56,6 +56,10 @@ bool CheckAndGetDBConfig(const JsonObject &config, const std::string &name, cons int errCode = E_OK; ValueObject configValue = config.GetObjectByPath(configField, errCode); + if (errCode != E_OK) { + GLOGE("Can not find config Value"); + return errCode; + } if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { GLOGE("Check DB config failed, not found or type of %s is not NUMBER.", name.c_str()); return false; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp index 820c7438..a967d2e6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp @@ -14,6 +14,8 @@ */ #include "json_common.h" +#include + #include "doc_errno.h" #include "log_print.h" @@ -82,26 +84,27 @@ std::vector JsonCommon::GetLeafValue(const JsonObject &node) bool JsonCommon::CheckNode(JsonObject &node) { - while (!node.IsNull()) { - int ret = 0; + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { std::set fieldSet; bool isFieldNameExist = true; - std::string fieldName = node.GetItemField(ret); + int ret = E_OK; + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); if (ret != E_OK) { isFieldNameExist = false; } - if (fieldSet.find(fieldName) != fieldSet.end()) { return false; } - if (isFieldNameExist) { fieldSet.insert(fieldName); if (fieldName.empty()) { return false; } } - for (size_t i = 0; i < fieldName.size(); i++) { if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || fieldName[i] == '_')) { return false; @@ -110,14 +113,12 @@ bool JsonCommon::CheckNode(JsonObject &node) return false; } } - - if (!node.GetChild().IsNull()) { - JsonObject nodeNew = node.GetChild(); - if (!CheckNode(nodeNew)) { - return false; - } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); + } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); } - node = node.GetNext(); } return true; } @@ -129,10 +130,14 @@ bool JsonCommon::CheckJsonField(JsonObject &jsonObj) bool JsonCommon::CheckProjectionNode(JsonObject &node, bool isFirstLevel, int &errCode) { - while (!node.IsNull()) { + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { int ret = 0; std::set fieldSet; - std::string fieldName = node.GetItemField(ret); + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); if (fieldName.empty()) { errCode = -E_INVALID_ARGS; return false; @@ -154,13 +159,12 @@ bool JsonCommon::CheckProjectionNode(JsonObject &node, bool isFirstLevel, int &e return false; } } - if (!node.GetChild().IsNull()) { - JsonObject nodeNew = node.GetChild(); - if (!CheckProjectionNode(nodeNew, false, errCode)) { - return false; - } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); + } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); } - node = node.GetNext(); } return true; } @@ -214,8 +218,7 @@ int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, } if (!node.GetChild().IsNull() && node.GetChild().GetItemField() != "") { JsonObject nodeNew = node.GetChild(); - int ret = E_OK; - ret = ParseNode(nodeNew, singlePath, resultPath, false); + int ret = ParseNode(nodeNew, singlePath, resultPath, false); if (ret != E_OK) { return ret; } @@ -340,7 +343,7 @@ bool AddSpliteHitField(const JsonObject &src, const JsonObject &item, JsonFieldP return true; } - for (int32_t i = (int32_t)abandonPath.size() - 1; i > -1; i--) { + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { GLOGE("Add collapse item to object failed, path not exist."); externErrCode = -E_DATA_CONFLICT; @@ -382,7 +385,7 @@ bool AddSpliteField(const JsonObject &src, const JsonObject &item, const JsonFie return false; } JsonFieldPath newHitPath; - for (int32_t i = (int32_t)abandonPath.size() - 1; i > -1; i--) { + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { GLOGE("Add collapse item to object failed, path not exist."); externErrCode = -E_DATA_CONFLICT; @@ -538,8 +541,8 @@ int JsonCommon::Append(const JsonObject &src, const JsonObject &add, bool isRepl { int externErrCode = E_OK; JsonObjectIterator(add, {}, - [&src, &externErrCode, &isReplace](const JsonFieldPath &path, const JsonObject &father, - const JsonObject &item) { + [&src, &externErrCode, &isReplace](const JsonFieldPath &path, + const JsonObject &father, const JsonObject &item) { bool isCollapse = false; // Whether there is a path generated by the dot operator, such as t1.t2.t3 JsonFieldPath itemPath = ExpendPathForField(path, isCollapse); if (src.IsFieldExists(itemPath)) { @@ -639,7 +642,7 @@ bool JsonCommon::IsObjectItemMatch(const JsonObject &srcItem, const JsonObject & bool JsonCommon::JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, bool &isCollapse, int &isMatchFlag) { - int errCode; + int errCode = E_OK; JsonObject srcItem = src.FindItemPowerMode(itemPath, errCode); if (errCode != -E_JSON_PATH_NOT_EXISTS && srcItem == item) { isMatchFlag = true; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp index 52891fe1..8b179159 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp @@ -75,7 +75,7 @@ bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::st return true; } -int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector> &filterPath) +int CheckCommon::CheckFilter(JsonObject &filterObj, std::vector> &filterPath, bool &isIdExist) { for (size_t i = 0; i < filterPath.size(); i++) { if (filterPath[i].size() > JSON_DEEP_MAX) { @@ -83,9 +83,6 @@ int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector< return -E_INVALID_ARGS; } } - if (!filterObj.GetChild().GetNext().IsNull()) { // check contained other field at the same level as the id node - isOnlyId = false; - } for (size_t i = 0; i < filterPath.size(); i++) { if (filterPath[i].empty()) { return -E_INVALID_JSON_FORMAT; @@ -104,15 +101,11 @@ int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector< return -E_INVALID_ARGS; } } - bool isIdExisit = false; - int ret = CheckIdFormat(filterObj, isIdExisit); + int ret = CheckIdFormat(filterObj, isIdExist); if (ret != E_OK) { GLOGE("Filter Id format is illegal"); return ret; } - if (!isIdExisit) { - isOnlyId = false; - } return E_OK; } @@ -132,18 +125,13 @@ int CheckCommon::CheckIdFormat(JsonObject &filterJson, bool &isIdExisit) return E_OK; } -int CheckCommon::CheckDocument(JsonObject &documentObj) +int CheckCommon::CheckDocument(JsonObject &documentObj, bool &isIdExist) { if (documentObj.GetDeep() > JSON_DEEP_MAX) { GLOGE("documentObj's json deep is deeper than JSON_DEEP_MAX"); return -E_INVALID_ARGS; } - bool isIdExist = true; int ret = CheckIdFormat(documentObj, isIdExist); - if (!isIdExist) { - GLOGE("Document Id format is illegal"); - return -E_INVALID_ARGS; - } if (ret != E_OK) { return ret; } @@ -185,7 +173,7 @@ int CheckCommon::CheckUpdata(JsonObject &updataObj) if (errCode != E_OK) { return errCode; } - for (auto fieldName : allFieldsName) { + for (const auto &fieldName : allFieldsName) { for (auto oneChar : fieldName) { if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { GLOGE("updata fieldName is illegal"); @@ -226,7 +214,7 @@ int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &filterPath); - static int CheckIdFormat(JsonObject &filterJson, bool &isIdExisit); - static int CheckDocument(JsonObject &documentObj); - static int CheckUpdata(JsonObject &updata); + static int CheckFilter(JsonObject &document, std::vector> &filterPath, bool &isIdExist); + static int CheckIdFormat(JsonObject &data, bool &isIdExisit); + static int CheckDocument(JsonObject &documentObj, bool &isIdExist); + static int CheckUpdata(JsonObject &updataObj); static int CheckProjection(JsonObject &projectionObj, std::vector> &path); }; using Key = std::vector; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h index c04f5c7b..30d109ed 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h @@ -25,21 +25,19 @@ namespace DocumentDB { class Collection { public: Collection(const std::string &name, KvStoreExecutor *executor); - Collection(const Collection &other); - Collection() {}; ~Collection(); - int PutDocument(const Key &key, const Value &document); - int InsertDocument(const Key &key, const Value &document); - int GetDocument(const Key &key, Value &document) const; - int GetMatchedDocument(const JsonObject &filterObj, std::vector> &values) const; - int DeleteDocument(const Key &key); + int InsertDocument(const std::string &id, const std::string &document, bool &isIdExist); + int GetDocumentById(Key &key, Value &document) const; + int GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const; + int DeleteDocument(Key &key); int IsCollectionExists(int &errCode); - int UpsertDocument(const std::string &id, const std::string &document, bool isReplace = true); - bool FindDocument(); - int UpdateDocument(const std::string &id, const std::string &document, bool isReplace = false); + int UpsertDocument(const std::string &id, const std::string &newDocument, bool &isIdExist); + int UpdateDocument(const std::string &id, const std::string &document); private: + int InsertUntilSuccess(Key &key, const std::string &id, Value &valSet); std::string name_; KvStoreExecutor *executor_ = nullptr; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h index 274bc841..75f636b5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h @@ -40,6 +40,7 @@ constexpr int E_RESOURCE_BUSY = E_BASE + 50; constexpr int E_FAILED_MEMORY_ALLOCATE = E_BASE + 51; constexpr int E_INNER_ERROR = E_BASE + 52; constexpr int E_INVALID_FILE_FORMAT = E_BASE + 53; +constexpr int E_FAILED_FILE_OPERATION = E_BASE + 54; int TransferDocErr(int err); } // namespace DocumentDB diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h new file mode 100644 index 00000000..32dbd79e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DOCUMENT_KEY_H +#define DOCUMENT_KEY_H + +#include +#include + +#include "json_object.h" + +#define GRD_DOC_OID_TIME_SIZE 4 +#define GRD_DOC_OID_INCREMENTAL_VALUE_SIZE 2 +#define GRD_DOC_OID_SIZE (GRD_DOC_OID_TIME_SIZE + GRD_DOC_OID_INCREMENTAL_VALUE_SIZE) +#define GRD_DOC_OID_HEX_SIZE (GRD_DOC_OID_SIZE * 2) +#define GRD_DOC_ID_TYPE_SIZE 1 + +namespace DocumentDB { +enum class DocIdType { + INT = 1, + STRING, +}; + +struct DocKey { +public: + int32_t keySize; + std::string key; + uint8_t type; +}; + +class DocumentKey { +public: + static int GetOidDocKey(DocKey &key); +}; +} // namespace DocumentDB +#endif // DOCUMENT_KEY_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h index cefdc9e3..3f1deacb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h @@ -69,13 +69,12 @@ public: private: int UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, bool &isReplace); - int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, JsonObject &documentObj, - bool &isReplace); - int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj); + int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &document, + JsonObject &documentObj, bool &isReplace); + int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj, + bool &isIdExist); int DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj); int InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context); - int CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, - std::string &docId, Collection &coll); KvStoreExecutor *executor_ = nullptr; std::map collections_; std::function closeNotifier_; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h index 65956e09..01c42c63 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h @@ -16,6 +16,7 @@ #ifndef RESULTSET_H #define RESULTSET_H +#include #include #include @@ -30,24 +31,27 @@ class ResultSet { public: ResultSet(); ~ResultSet(); - int Init(std::shared_ptr &context, DocumentStore *store, bool ifField); + int Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch); int GetNext(bool isNeedTransaction = false, bool isNeedCheckTable = false); int GetValue(char **value); + int GetValue(std::string &value); int GetKey(std::string &key); int EraseCollection(); private: int GetNextInner(bool isNeedCheckTable); - int CutJsonBranch(std::string &jsonData); + int GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData); + int CutJsonBranch(std::string &jsonKey, std::string &jsonData); int CheckCutNode(JsonObject *node, std::vector singleCutPath, std::vector> &allCutPath); int GetNextWithField(); DocumentStore *store_ = nullptr; - bool ifField_ = false; + bool isCutBranch_ = false; size_t index_ = 0; std::shared_ptr context_; - std::vector> matchDatas_; + std::pair matchData_; + std::string lastKeyIndex_; }; } // namespace DocumentDB #endif // RESULTSET_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h index 0a59f9ff..abdf5c9b 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h @@ -25,6 +25,6 @@ namespace DocumentDB { class ValueObject; -int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField); +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch); } // namespace DocumentDB #endif // RESULTSET_COMMON_H diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp index 1e6d04f2..61f6d2da 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp @@ -18,11 +18,10 @@ #include "check_common.h" #include "db_constant.h" #include "doc_errno.h" +#include "document_key.h" #include "log_print.h" namespace DocumentDB { -constexpr int JSON_LENS_MAX = 1024 * 1024; - Collection::Collection(const std::string &name, KvStoreExecutor *executor) : executor_(executor) { std::string lowerCaseName = name; @@ -32,26 +31,24 @@ Collection::Collection(const std::string &name, KvStoreExecutor *executor) : exe name_ = DBConstant::COLL_PREFIX + lowerCaseName; } -Collection::Collection(const Collection &other) -{ - name_ = other.name_; - executor_ = other.executor_; -} - Collection::~Collection() { executor_ = nullptr; } -int Collection::PutDocument(const Key &key, const Value &document) +int Collection::InsertUntilSuccess(Key &key, const std::string &id, Value &valSet) { - if (executor_ == nullptr) { - return -E_INNER_ERROR; - } - return executor_->PutData(name_, key, document); + DocKey docKey; + key.assign(id.begin(), id.end()); + int errCode = executor_->InsertData(name_, key, valSet); + while (errCode == -E_DATA_CONFLICT) { // if id alreay exist, create new one. + DocumentKey::GetOidDocKey(docKey); + key.assign(docKey.key.begin(), docKey.key.end()); + errCode = executor_->InsertData(name_, key, valSet); + } + return errCode; } - -int Collection::InsertDocument(const Key &key, const Value &document) +int Collection::InsertDocument(const std::string &id, const std::string &document, bool &isIdExist) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -64,36 +61,24 @@ int Collection::InsertDocument(const Key &key, const Value &document) if (!isCollectionExist) { return -E_INVALID_ARGS; } - return executor_->InsertData(name_, key, document); -} - -bool Collection::FindDocument() -{ - if (executor_ == nullptr) { - return -E_INNER_ERROR; - } - int errCode = E_OK; - return executor_->IsCollectionExists(name_, errCode); -} - -int Collection::GetDocument(const Key &key, Value &document) const -{ - if (executor_ == nullptr) { - return -E_INNER_ERROR; + Key key; + Value valSet(document.begin(), document.end()); + if (!isIdExist) { + return InsertUntilSuccess(key, id, valSet); } - return executor_->GetData(name_, key, document); + key.assign(id.begin(), id.end()); + return executor_->InsertData(name_, key, valSet); } -int Collection::GetMatchedDocument(const JsonObject &filterObj, - std::vector> &values) const +int Collection::GetDocumentById(Key &key, Value &document) const { if (executor_ == nullptr) { return -E_INNER_ERROR; } - return executor_->GetFieldedData(name_, filterObj, values); + return executor_->GetDataById(name_, key, document); } -int Collection::DeleteDocument(const Key &key) +int Collection::DeleteDocument(Key &key) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -109,12 +94,21 @@ int Collection::DeleteDocument(const Key &key) return executor_->DelData(name_, key); } +int Collection::GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const +{ + if (executor_ == nullptr) { + return -E_INNER_ERROR; + } + return executor_->GetDataByFilter(name_, key, filterObj, values, isIdExist); +} + int Collection::IsCollectionExists(int &errCode) { return executor_->IsCollectionExists(name_, errCode); } -int Collection::UpsertDocument(const std::string &id, const std::string &document, bool isReplace) +int Collection::UpsertDocument(const std::string &id, const std::string &newDocument, bool &isDataExist) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -129,47 +123,16 @@ int Collection::UpsertDocument(const std::string &id, const std::string &documen GLOGE("Collection not created."); return -E_INVALID_ARGS; } - - JsonObject upsertValue = JsonObject::Parse(document, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse upsert value failed. %d", errCode); - return errCode; + Key key; + Value valSet(newDocument.begin(), newDocument.end()); + if (!isDataExist) { + return InsertUntilSuccess(key, id, valSet); } - - Key keyId(id.begin(), id.end()); - Value valSet(document.begin(), document.end()); - if (!isReplace) { - Value valueGot; - errCode = executor_->GetData(name_, keyId, valueGot); - std::string valueGotStr = std::string(valueGot.begin(), valueGot.end()); - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - GLOGW("Get original document failed. %d", errCode); - return errCode; - } else if (errCode == E_OK) { // document has been inserted - GLOGD("Document has been inserted, append value."); - JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); - return errCode; - } - - errCode = JsonCommon::Append(originValue, upsertValue, isReplace); - if (errCode != E_OK) { - GLOGD("Append value failed. %d", errCode); - return errCode; - } - std::string valStr = originValue.Print(); - if (valStr.length() >= JSON_LENS_MAX) { - GLOGE("document's length is too long"); - return -E_OVER_LIMIT; - } - valSet = { valStr.begin(), valStr.end() }; - } - } - return executor_->PutData(name_, keyId, valSet); + key.assign(id.begin(), id.end()); + return executor_->PutData(name_, key, valSet); } -int Collection::UpdateDocument(const std::string &id, const std::string &update, bool isReplace) +int Collection::UpdateDocument(const std::string &id, const std::string &newDocument) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -184,40 +147,8 @@ int Collection::UpdateDocument(const std::string &id, const std::string &update, GLOGE("Collection not created."); return -E_INVALID_ARGS; } - - JsonObject updateValue = JsonObject::Parse(update, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse upsert value failed. %d", errCode); - return errCode; - } - Key keyId(id.begin(), id.end()); - Value valueGot; - errCode = executor_->GetData(name_, keyId, valueGot); - std::string valueGotStr = std::string(valueGot.begin(), valueGot.end()); - if (errCode == -E_NOT_FOUND) { - GLOGW("Get original document not found."); - return -E_NOT_FOUND; - } else if (errCode != E_OK) { - GLOGE("Get original document failed. %d", errCode); - return errCode; - } - JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); - return errCode; - } - errCode = JsonCommon::Append(originValue, updateValue, isReplace); - if (errCode != E_OK) { - GLOGD("Append value failed. %d", errCode); - return errCode; - } - std::string valStr = originValue.Print(); - if (valStr.length() >= JSON_LENS_MAX) { - GLOGE("document's length is too long"); - return -E_OVER_LIMIT; - } - Value valSet(valStr.begin(), valStr.end()); + Value valSet(newDocument.begin(), newDocument.end()); return executor_->PutData(name_, keyId, valSet); } } // namespace DocumentDB diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp index 3c8887e9..bf9dca10 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp @@ -21,8 +21,8 @@ namespace DocumentDB { int GetErrorCategory(int errCode) { int categoryCode = errCode % 1000000; // 1000000: mod to get last 6 digits - categoryCode /= 1000; // 1000: deviced to remove first 3 digits - categoryCode *= 1000; // 1000: multiply to pad the output + categoryCode /= 1000; // 1000: deviced to remove first 3 digits + categoryCode *= 1000; // 1000: multiply to pad the output return categoryCode; } @@ -63,6 +63,8 @@ int TransferDocErr(int err) return GetErrorCategory(GRD_FAILED_MEMORY_ALLOCATE); case -E_INVALID_FILE_FORMAT: return GetErrorCategory(GRD_INVALID_FILE_FORMAT); + case -E_FAILED_FILE_OPERATION: + return GetErrorCategory(GRD_FAILED_FILE_OPERATION); case -E_INNER_ERROR: default: return GetErrorCategory(GRD_INNER_ERR); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp new file mode 100644 index 00000000..a6493205 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "document_key.h" + +#include "doc_errno.h" +#include "log_print.h" +#include "securec.h" +namespace DocumentDB { +static uint16_t g_oIdIncNum = 0; +constexpr uint16_t MAX_NUMBER_OF_AUTOINCREMENTS = 65535; +constexpr uint16_t UINT_ZERO = 0; +static int InitDocIdFromOid(DocKey &docKey) +{ + time_t nowTime = time(nullptr); + if (nowTime < 0) { + return -E_INNER_ERROR; + } + uint32_t now = (uint32_t)nowTime; + uint16_t iv = g_oIdIncNum++; + // The maximum number of autoincrements is 65535, and if it is exceeded, it becomes 0. + if (g_oIdIncNum > MAX_NUMBER_OF_AUTOINCREMENTS) { + g_oIdIncNum = UINT_ZERO; + } + char *idTemp = new char[GRD_DOC_OID_HEX_SIZE + 1]; + if (sprintf_s(idTemp, GRD_DOC_OID_HEX_SIZE + 1, "%08x%04x", now, iv) < 0) { + GLOGE("get oid error"); + return -E_INNER_ERROR; + } + docKey.key = idTemp; + delete[] idTemp; + return E_OK; +} + +int DocumentKey::GetOidDocKey(DocKey &key) +{ + int ret = InitDocIdFromOid(key); + return ret; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp index caa230c1..83dac352 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp @@ -18,6 +18,7 @@ #include "check_common.h" #include "collection_option.h" #include "doc_errno.h" +#include "document_key.h" #include "grd_base/grd_type_export.h" #include "grd_resultset_inner.h" #include "log_print.h" @@ -43,7 +44,6 @@ int DocumentStore::CreateCollection(const std::string &name, const std::string & GLOGE("Check collection name invalid. %d", errCode); return errCode; } - errCode = E_OK; CollectionOption collOption = CollectionOption::ReadOption(option, errCode); if (errCode != E_OK) { @@ -128,7 +128,7 @@ END: return errCode; } -int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isOnlyId) +int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isIdExist) { int errCode = E_OK; filterAllPath = JsonCommon::ParsePath(filterObj, errCode); @@ -136,7 +136,7 @@ int TranFilter(JsonObject &filterObj, std::vector> &fil GLOGE("filter ParsePath failed"); return errCode; } - return CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); + return CheckCommon::CheckFilter(filterObj, filterAllPath, isIdExist); } int UpdateArgsCheck(const std::string &collection, const std::string &filter, const std::string &update, uint32_t flags) @@ -170,6 +170,41 @@ int UpdateArgsCheck(const std::string &collection, const std::string &filter, co return errCode; } +int GetUpDataRePlaceData(ResultSet &resultSet, const std::string &id, const std::string &update, std::string &valStr, + bool isReplace) +{ + std::string valueGotStr; + int errCode = resultSet.GetValue(valueGotStr); + if (errCode == -E_NO_DATA) { + GLOGW("Get original document not found."); + return -E_NOT_FOUND; + } else if (errCode != E_OK) { + GLOGE("Get original document failed. %d", errCode); + return errCode; + } + JsonObject updateValue = JsonObject::Parse(update, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse upsert value failed. %d", errCode); + return errCode; + } + JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, updateValue, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, bool &isReplace) { @@ -183,26 +218,28 @@ int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, Json } std::string docId; int count = 0; + std::string valStr; auto coll = Collection(context->collectionName, executor_); - if (context->isOnlyId) { - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - docId = idValue.GetStringValue(); - } else { - ResultSet resultSet; - InitResultSet(context, this, resultSet, true); - // no start transaction inner - errCode = resultSet.GetNext(false, true); - if (errCode == -E_NO_DATA) { - // no need to set count - errCode = E_OK; - goto END; - } else if (errCode != E_OK) { - goto END; - } - resultSet.GetKey(docId); + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; } - errCode = coll.UpdateDocument(docId, update, isReplace); + // no start transaction inner + errCode = resultSet.GetNext(false, true); + if (errCode == -E_NO_DATA) { + // no need to set count + errCode = E_OK; + goto END; + } else if (errCode != E_OK) { + goto END; + } + resultSet.GetKey(docId); + errCode = GetUpDataRePlaceData(resultSet, docId, update, valStr, isReplace); + if (errCode != E_OK) { + goto END; + } + errCode = coll.UpdateDocument(docId, valStr); if (errCode == E_OK) { count++; } else if (errCode == -E_NOT_FOUND) { @@ -229,17 +266,18 @@ int DocumentStore::UpdateDocument(const std::string &collection, const std::stri GLOGE("filter Parsed failed"); return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { return errCode; } bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; context->collectionName = collection; - context->isOnlyId = isOnlyId; context->filter = filter; + context->ifShowId = true; return UpdateDataIntoDB(context, filterObj, update, isReplace); } @@ -263,28 +301,86 @@ int UpsertArgsCheck(const std::string &collection, const std::string &filter, co return errCode; } -int DocumentStore::CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, - std::string &docId, Collection &coll) +int CheckUpsertConflict(ResultSet &resultSet, JsonObject &filterObj, std::string &docId, Collection &coll, + bool &isDataExist) { - ResultSet resultSet; - InitResultSet(context, this, resultSet, true); - int errCode = resultSet.GetNext(false, true); - bool isfilterMatch = false; + std::string val; // use to know whether there is data in the resultSet or not. + int errCode = resultSet.GetValue(val); if (errCode == E_OK) { - isfilterMatch = true; + isDataExist = true; } Value ValueDocument; - Key key(docId.begin(), docId.end()); - errCode = coll.GetDocument(key, ValueDocument); - if (errCode == E_OK && !(isfilterMatch)) { + Key id(docId.begin(), docId.end()); + errCode = coll.GetDocumentById(id, ValueDocument); + if (errCode == E_OK && !(isDataExist)) { GLOGE("id exist but filter does not match, data conflict"); errCode = -E_DATA_CONFLICT; } return errCode; } +int GetUpsertRePlaceData(ResultSet &resultSet, JsonObject &documentObj, bool isReplace, std::string &valStr) +{ + int errCode = resultSet.GetValue(valStr); + if (errCode != E_OK || isReplace) { + valStr = documentObj.Print(); // If cant not find data, insert it. + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return E_OK; + } + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + GLOGW("Get original document failed. %d", errCode); + return errCode; + } else if (errCode == E_OK) { // document has been inserted + JsonObject originValue = JsonObject::Parse(valStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, documentObj, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + } + return errCode; +} + +int InsertIdToDocument(ResultSet &resultSet, JsonObject &filterObj, JsonObject &documentObj, std::string &docId) +{ + auto filterObjChild = filterObj.GetChild(); + bool isIdExist; + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); + int errCode = E_OK; + int ret = resultSet.GetNext(false, true); // All anomalies will be judged later + if (ret != E_OK && ret != -E_NO_DATA) { + return ret; + } + if (isIdExist) { + docId = idValue.GetStringValue(); + JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); // this errCode will always be E_OK. + documentObj.InsertItemObject(0, idObj); + } else { + if (ret == E_OK) { // E_OK means find data. + (void)resultSet.GetKey(docId); // This errCode will always be E_OK. + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + docId = docKey.key; + } + } + return errCode; +} + int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, - JsonObject &documentObj, bool &isReplace) + const std::string &document, JsonObject &documentObj, bool &isReplace) { std::lock_guard lock(dbMutex_); if (executor_ == nullptr) { @@ -296,29 +392,29 @@ int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, Json } Collection coll = Collection(context->collectionName, executor_); int count = 0; - std::string targetDocument; std::string docId; - bool isIdExist; - auto filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); - docId = idValue.GetStringValue(); - JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); - documentObj.InsertItemObject(0, idObj); - targetDocument = documentObj.Print(); - if (!isIdExist) { - errCode = -E_INVALID_ARGS; + ResultSet resultSet; + std::string newDocument; + bool isDataExist = false; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { goto END; } - if (!context->isOnlyId) { - errCode = CheckUpsertConflict(isIdExist, context, filterObj, docId, coll); - // There are only three return values, E_ OK and - E_ NO_DATA is a normal scenario, - // and that situation can continue to move forward - if (errCode == -E_DATA_CONFLICT) { - GLOGE("upsert data conflict"); - goto END; - } + errCode = InsertIdToDocument(resultSet, filterObj, documentObj, docId); + if (errCode != E_OK) { + goto END; + } + errCode = CheckUpsertConflict(resultSet, filterObj, docId, coll, isDataExist); + // There are only three return values, the two other situation can continue to move forward. + if (errCode == -E_DATA_CONFLICT) { + GLOGE("upsert data conflict"); + goto END; } - errCode = coll.UpsertDocument(docId, targetDocument, isReplace); + errCode = GetUpsertRePlaceData(resultSet, documentObj, isReplace, newDocument); + if (errCode != E_OK) { + goto END; + } + errCode = coll.UpsertDocument(docId, newDocument, isDataExist); if (errCode == E_OK) { count++; } else if (errCode == -E_NOT_FOUND) { @@ -345,6 +441,7 @@ int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentO } return errCode; } + int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, uint32_t flags) { @@ -367,19 +464,20 @@ int DocumentStore::UpsertDocument(const std::string &collection, const std::stri GLOGE("document format is illegal"); return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { GLOGE("filter is invalid"); return errCode; } std::shared_ptr context = std::make_shared(); context->filter = filter; - context->isOnlyId = isOnlyId; context->collectionName = collection; + context->ifShowId = true; + context->isIdExist = isIdExist; bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); - return UpsertDataIntoDB(context, filterObj, documentObj, isReplace); + return UpsertDataIntoDB(context, filterObj, document, documentObj, isReplace); } int InsertArgsCheck(const std::string &collection, const std::string &document, uint32_t flags) @@ -401,16 +499,22 @@ int InsertArgsCheck(const std::string &collection, const std::string &document, return errCode; } -int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj) +int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, + JsonObject &documentObj, bool &isIdExist) { std::lock_guard lock(dbMutex_); - JsonObject documentObjChild = documentObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); - std::string id = idValue.GetStringValue(); - Key key(id.begin(), id.end()); - Value value(document.begin(), document.end()); + std::string id; + if (isIdExist) { + JsonObject documentObjChild = documentObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); + id = idValue.GetStringValue(); + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + id = docKey.key; + } Collection coll = Collection(collection, executor_); - return coll.InsertDocument(key, value); + return coll.InsertDocument(id, document, isIdExist); } int DocumentStore::InsertDocument(const std::string &collection, const std::string &document, uint32_t flags) @@ -424,11 +528,12 @@ int DocumentStore::InsertDocument(const std::string &collection, const std::stri GLOGE("Document Parsed failed"); return errCode; } - errCode = CheckCommon::CheckDocument(documentObj); + bool isIdExist = true; + errCode = CheckCommon::CheckDocument(documentObj, isIdExist); if (errCode != E_OK) { return errCode; } - return InsertDataIntoDB(collection, document, documentObj); + return InsertDataIntoDB(collection, document, documentObj, isIdExist); } int DeleteArgsCheck(const std::string &collection, const std::string &filter, uint32_t flags) @@ -466,19 +571,16 @@ int DocumentStore::DeleteDataFromDB(std::shared_ptr &context, Json return errCode; } std::string id; - if (context->isOnlyId) { - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - id = idValue.GetStringValue(); - } else { - ResultSet resultSet; - InitResultSet(context, this, resultSet, true); - errCode = resultSet.GetNext(false, true); - if (errCode != E_OK) { - goto END; - } - resultSet.GetKey(id); + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; + } + errCode = resultSet.GetNext(false, true); + if (errCode != E_OK) { + goto END; } + resultSet.GetKey(id); END: if (errCode == E_OK) { Key key(id.begin(), id.end()); @@ -501,16 +603,16 @@ int DocumentStore::DeleteDocument(const std::string &collection, const std::stri if (errCode != E_OK) { return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { return errCode; } std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; context->filter = filter; context->collectionName = collection; - context->isOnlyId = isOnlyId; return DeleteDataFromDB(context, filterObj); } Collection DocumentStore::GetCollection(std::string &collectionName) @@ -655,7 +757,7 @@ int DocumentStore::InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_pt if (errCode != E_OK) { goto END; } - errCode = InitResultSet(context, this, grdResultSet->resultSet_, false); + errCode = InitResultSet(context, this, grdResultSet->resultSet_, true); if (errCode == E_OK) { collections_[context->collectionName] = nullptr; } @@ -671,37 +773,36 @@ END: int DocumentStore::FindDocument(const std::string &collection, const std::string &filter, const std::string &projection, uint32_t flags, GRD_ResultSet *grdResultSet) { - std::shared_ptr context = std::make_shared(); - int errCode = E_OK; - errCode = FindArgsCheck(collection, filter, projection, flags); + int errCode = FindArgsCheck(collection, filter, projection, flags); if (errCode != E_OK) { GLOGE("delete arg is illegal"); return errCode; } - context->collectionName = collection; - context->filter = filter; JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; } + std::shared_ptr context = std::make_shared(); errCode = FindProjectionInit(projection, context); if (errCode != E_OK) { return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { GLOGE("filter is invalid"); return errCode; } - context->isOnlyId = isOnlyId; if (flags == GRD_DOC_ID_DISPLAY) { context->ifShowId = true; } else { context->ifShowId = false; } + context->collectionName = collection; + context->filter = filter; + context->isIdExist = isIdExist; return InitFindResultSet(grdResultSet, context); } @@ -769,7 +870,8 @@ int DocumentStore::Rollback() bool DocumentStore::IsCollectionExists(const std::string &collectionName, int &errCode) { if (executor_ == nullptr) { - return -E_INNER_ERROR; + errCode = -E_INNER_ERROR; + return false; } return executor_->IsCollectionExists(collectionName, errCode); } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp index 225a8bc8..4335a97f 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp @@ -15,6 +15,7 @@ #include "result_set.h" #include "db_constant.h" +#include "document_key.h" #include "log_print.h" #include "securec.h" @@ -33,59 +34,65 @@ int ResultSet::EraseCollection() } return E_OK; } -int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool ifField) +int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch) { - ifField_ = ifField; + isCutBranch_ = isCutBranch; context_ = context; store_ = store; return E_OK; } -int ResultSet::GetNextWithField() +int ResultSet::GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData) { - int errCode = E_OK; - if (context_->isOnlyId) { - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); + std::pair value; + Collection coll = store_->GetCollection(context_->collectionName); + filterObj.DeleteItemFromObject(KEY_ID); + int errCode = coll.GetMatchedDocument(filterObj, key, value, context_->isIdExist); + if (errCode == -E_NOT_FOUND) { + return -E_NO_DATA; + } + jsonData.assign(value.second.begin(), value.second.end()); + jsonKey.assign(value.first.begin(), value.first.end()); + lastKeyIndex_ = jsonKey; + if (isCutBranch_) { + errCode = CutJsonBranch(jsonKey, jsonData); if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - JsonObject filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - std::string idKey = idValue.GetStringValue(); - if (idKey.empty()) { - return -E_NO_DATA; + GLOGE("cut branch faild"); } - Key key(idKey.begin(), idKey.end()); - Value document; - Collection coll = store_->GetCollection(context_->collectionName); - errCode = coll.GetDocument(key, document); - if (errCode == -E_NOT_FOUND) { + } + return errCode; +} + +int ResultSet::GetNextWithField() +{ + int errCode = E_OK; + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + Key key; + if (context_->isIdExist) { + if (index_ == 0) { // get id from filter, if alreay has got id once, get from lastKeyIndex. + JsonObject filterObjChild = filterObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); + std::string idKey = idValue.GetStringValue(); + key.assign(idKey.begin(), idKey.end()); + } else { // Use id to find data that can only get one data. + matchData_.first.clear(); // Delete previous data. + matchData_.second.clear(); return -E_NO_DATA; } - std::string jsonData(document.begin(), document.end()); - CutJsonBranch(jsonData); - std::vector> values; - values.emplace_back(std::make_pair(idKey, jsonData)); - matchDatas_ = values; } else { - Collection coll = store_->GetCollection(context_->collectionName); - std::vector> values; - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - errCode = coll.GetMatchedDocument(filterObj, values); - if (errCode == -E_NOT_FOUND) { - return -E_NO_DATA; - } - for (size_t i = 0; i < values.size(); i++) { - CutJsonBranch(values[i].second); - } - matchDatas_ = values; + key.assign(lastKeyIndex_.begin(), lastKeyIndex_.end()); } - return E_OK; + matchData_.first.clear(); + matchData_.second.clear(); + std::string jsonKey; + std::string jsonData; + errCode = GetValueFromDB(key, filterObj, jsonKey, jsonData); + matchData_ = std::make_pair(jsonKey, jsonData); + return errCode; } int ResultSet::GetNextInner(bool isNeedCheckTable) @@ -104,27 +111,12 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) return -E_INVALID_ARGS; } } - if (!ifField_ && index_ == 0) { - errCode = GetNextWithField(); - if (errCode != E_OK) { - return errCode; - } - } else if (index_ == 0) { - Collection coll = store_->GetCollection(context_->collectionName); - std::vector> values; - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - errCode = coll.GetMatchedDocument(filterObj, values); - if (errCode == -E_NOT_FOUND) { - return -E_NO_DATA; - } - matchDatas_ = values; - } + errCode = GetNextWithField(); index_++; - if (index_ > matchDatas_.size()) { + if (errCode != E_OK) { + return errCode; + } + if (matchData_.second.empty()) { return -E_NO_DATA; } return E_OK; @@ -132,13 +124,13 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) int ResultSet::GetNext(bool isNeedTransaction, bool isNeedCheckTable) { - int errCode = E_OK; if (!isNeedTransaction) { return GetNextInner(isNeedCheckTable); } std::lock_guard lock(store_->dbMutex_); - errCode = store_->StartTransaction(); + int errCode = store_->StartTransaction(); if (errCode != E_OK) { + GLOGE("Start transaction faild"); return errCode; } errCode = GetNextInner(isNeedCheckTable); @@ -153,11 +145,11 @@ int ResultSet::GetNext(bool isNeedTransaction, bool isNeedCheckTable) int ResultSet::GetValue(char **value) { std::lock_guard lock(store_->dbMutex_); - if (index_ == 0 || (index_ > matchDatas_.size())) { + if (matchData_.first.empty()) { GLOGE("The value vector in resultSet is empty"); return -E_NO_DATA; } - std::string jsonData = matchDatas_[index_ - 1].second; + std::string jsonData = matchData_.second; char *jsonstr = new char[jsonData.size() + 1]; if (jsonstr == nullptr) { GLOGE("Memory allocation failed!"); @@ -173,13 +165,23 @@ int ResultSet::GetValue(char **value) return E_OK; } -int ResultSet::GetKey(std::string &key) +int ResultSet::GetValue(std::string &value) { - if (index_ == 0 || (index_ > matchDatas_.size())) { + if (matchData_.first.empty()) { GLOGE("The value vector in resultSet is empty"); return -E_NO_DATA; } - key = matchDatas_[index_ - 1].first; + value = matchData_.second; + return E_OK; +} + +int ResultSet::GetKey(std::string &key) +{ + key = matchData_.first; + if (key.empty()) { + GLOGE("can not get data, because it is empty"); + return -E_NO_DATA; + } return E_OK; } @@ -209,7 +211,32 @@ int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePat return E_OK; } -int ResultSet::CutJsonBranch(std::string &jsonData) +JsonObject CreatIdObj(const std::string &idStr, int errCode) +{ + std::stringstream sstream; + sstream << "{\"_id\":" + << "\"" << idStr << "\"}"; + JsonObject idObj = JsonObject::Parse(sstream.str(), errCode, true); // cant be faild. + return idObj; +} + +int InsertId(JsonObject &cjsonObj, std::string &jsonKey) +{ + if (jsonKey.empty()) { + GLOGE("Genalral Id faild"); + return -E_INNER_ERROR; + } + int errCode = E_OK; + JsonObject idObj = CreatIdObj(jsonKey, errCode); + if (errCode != E_OK) { + GLOGE("CreatIdObj faild"); + return errCode; + } + cjsonObj.InsertItemObject(0, idObj.GetChild()); // idObj's child is _id node + return E_OK; +} + +int ResultSet::CutJsonBranch(std::string &jsonKey, std::string &jsonData) { int errCode; JsonObject cjsonObj = JsonObject::Parse(jsonData, errCode, true); @@ -217,6 +244,12 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("jsonData Parsed failed"); return errCode; } + bool isIdExistInValue = true; // if id exsit in the value string that get from db. + bool isInsertIdflag = false; + isIdExistInValue = cjsonObj.GetObjectItem("_id", errCode).IsNull() ? false : true; + if (context_->ifShowId && !isIdExistInValue) { + isInsertIdflag = true; // ifShowId is true,and then the data taken out does not have IDs, insert id. + } if (context_->viewType) { std::vector singlePath; JsonObject cjsonObjChild = cjsonObj.GetChild(); @@ -226,12 +259,21 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("The node in CheckCutNode is nullptr"); return errCode; } - for (const auto &singleCutPaht : allCutPath) { - if (!context_->ifShowId || singleCutPaht[0] != KEY_ID) { - cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); + for (const auto &singleCutPath : allCutPath) { + if (!context_->ifShowId || singleCutPath[0] != KEY_ID) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPath); + } + if (singleCutPath[0] == KEY_ID && !isIdExistInValue) { // projection has Id, and its showType is true. + isInsertIdflag = true; } } } + if (isInsertIdflag) { + errCode = InsertId(cjsonObj, jsonKey); + if (errCode != E_OK) { + return errCode; + } + } if (!context_->viewType) { for (const auto &singleCutPaht : context_->projectionPath) { cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp index d6e070aa..dd9acaeb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp @@ -14,20 +14,26 @@ */ #include "result_set_common.h" - +#include "grd_format_config.h" #include "doc_errno.h" #include "grd_base/grd_error.h" namespace DocumentDB { class ValueObject; -int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField) +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch) { - if (!ifField) { + if (isCutBranch) { + for (const auto &singlePath : context->projectionPath) { + if (singlePath[0] == KEY_ID && context->viewType == true) { // projection has Id and viewType is true + context->ifShowId = true; + break; + } + } if (context->projectionTree.ParseTree(context->projectionPath) == -E_INVALID_ARGS) { GLOGE("Parse ProjectionTree failed"); return -E_INVALID_ARGS; } } - return resultSet.Init(context, store, ifField); + return resultSet.Init(context, store, isCutBranch); } } // namespace DocumentDB diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h index 9680c82c..bd1cba71 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h @@ -37,7 +37,6 @@ public: explicit ValueObject(bool val); explicit ValueObject(double val); explicit ValueObject(const char *val); - explicit ValueObject(const std::string &val); ValueType GetValueType() const; bool GetBoolValue() const; @@ -68,20 +67,17 @@ public: std::string Print() const; JsonObject GetObjectItem(const std::string &field, int &errCode); - JsonObject GetArrayItem(int index, int &errCode); JsonObject GetNext() const; JsonObject GetChild() const; int DeleteItemFromObject(const std::string &field); - int AddItemToObject(const JsonObject &item); int AddItemToObject(const std::string &fieldName, const JsonObject &item); int AddItemToObject(const std::string &fieldName); ValueObject GetItemValue() const; void ReplaceItemInArray(const int &index, const JsonObject &newItem, int &errCode); void ReplaceItemInObject(const std::string &fieldName, const JsonObject &newItem, int &errCode); - void SetItemValue(const ValueObject &value) const; int InsertItemObject(int which, const JsonObject &newItem); std::string GetItemField() const; @@ -92,7 +88,6 @@ public: JsonObject FindItem(const JsonFieldPath &jsonPath, int &errCode) const; JsonObject FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const; ValueObject GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const; - int DeleteItemOnTarget(const JsonFieldPath &path); int DeleteItemDeeplyOnTarget(const JsonFieldPath &path); bool IsNull() const; int GetDeep(); @@ -109,7 +104,7 @@ private: int CheckJsonRepeatField(cJSON *object, bool isFirstFloor); int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor); int GetDeep(cJSON *cjson); - int CheckNumber(cJSON *cjson, int &errCode); + int CheckNumber(cJSON *cJSON); cJSON *cjson_ = nullptr; int jsonDeep_ = 0; bool isOwner_ = false; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h index 7dd31d4e..a12bda14 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h @@ -29,18 +29,18 @@ public: virtual int Commit() = 0; virtual int Rollback() = 0; - virtual int PutData(const std::string &collName, const Key &key, const Value &value) = 0; - virtual int InsertData(const std::string &collName, const Key &key, const Value &value) = 0; - virtual int GetData(const std::string &collName, const Key &key, Value &value) const = 0; - virtual int GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const = 0; - virtual int DelData(const std::string &collName, const Key &key) = 0; + virtual int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int GetDataByKey(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataById(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const = 0; + virtual int DelData(const std::string &collName, Key &key) = 0; virtual int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) = 0; virtual int DropCollection(const std::string &name, bool ignoreNonExists) = 0; virtual bool IsCollectionExists(const std::string &name, int &errCode) = 0; - virtual int GetCollectionOption(const std::string &name, std::string &option) = 0; virtual int SetCollectionOption(const std::string &name, const std::string &option) = 0; virtual int CleanCollectionOption(const std::string &name) = 0; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp index 86357c71..26c50fd8 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp @@ -14,6 +14,7 @@ */ #include "json_object.h" + #include #include #include @@ -49,12 +50,6 @@ ValueObject::ValueObject(const char *val) stringValue = val; } -ValueObject::ValueObject(const std::string &val) -{ - valueType = ValueType::VALUE_STRING; - stringValue = val; -} - ValueObject::ValueType ValueObject::GetValueType() const { return valueType; @@ -102,7 +97,7 @@ JsonObject::~JsonObject() bool JsonObject::operator==(const JsonObject &other) const { - return (cJSON_Compare(this->cjson_, other.cjson_, 0) != 0); + return (cJSON_Compare(this->cjson_, other.cjson_, true) != 0); // CaseSensitive } bool JsonObject::IsNull() const @@ -150,17 +145,20 @@ int JsonObject::GetDeep(cJSON *cjson) return depth; } -int JsonObject::CheckNumber(cJSON *item, int &errCode) +int JsonObject::CheckNumber(cJSON *item) { std::queue cjsonQueue; cjsonQueue.push(item); while (!cjsonQueue.empty()) { cJSON *node = cjsonQueue.front(); cjsonQueue.pop(); - if (node != NULL && cJSON_IsNumber(node)) { + if (node == nullptr) { + return -E_INVALID_ARGS; + } + if (cJSON_IsNumber(node)) { // node is not null all the time double value = cJSON_GetNumberValue(node); if (value > __DBL_MAX__ || value < -__DBL_MAX__) { - errCode = -E_INVALID_ARGS; + return -E_INVALID_ARGS; } } if (node->child != nullptr) { @@ -188,8 +186,7 @@ int JsonObject::Init(const std::string &str, bool isFilter) return -E_INVALID_ARGS; } - int ret = 0; - CheckNumber(cjson_, ret); + int ret = CheckNumber(cjson_); if (ret == -E_INVALID_ARGS) { GLOGE("Int value is larger than double"); return -E_INVALID_ARGS; @@ -226,6 +223,16 @@ int JsonObject::CheckJsonRepeatField(cJSON *object, bool isFirstFloor) return ret; } +bool IsFieldNameLegal(const std::string &fieldName) +{ + for (auto oneChar : fieldName) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return false; + } + } + return true; +} + int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor) { if (subObj == nullptr) { @@ -235,10 +242,8 @@ int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int if (subObj->string != nullptr) { fieldName = subObj->string; if (!isFirstFloor) { - for (auto oneChar : fieldName) { - if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { - return -E_INVALID_ARGS; - } + if (!IsFieldNameLegal(fieldName)) { + return -E_INVALID_ARGS; } } if (!fieldName.empty() && isdigit(fieldName[0])) { @@ -291,22 +296,6 @@ JsonObject JsonObject::GetObjectItem(const std::string &field, int &errCode) return item; } -JsonObject JsonObject::GetArrayItem(int index, int &errCode) -{ - if (cjson_ == nullptr || cjson_->type != cJSON_Array) { - errCode = -E_INVALID_ARGS; - return JsonObject(); - } - - JsonObject item; - item.caseSensitive_ = caseSensitive_; - item.cjson_ = cJSON_GetArrayItem(cjson_, index); - if (item.cjson_ == nullptr) { - errCode = -E_NOT_FOUND; - } - return item; -} - JsonObject JsonObject::GetNext() const { if (cjson_ == nullptr) { @@ -344,18 +333,6 @@ int JsonObject::DeleteItemFromObject(const std::string &field) return E_OK; } -int JsonObject::AddItemToObject(const JsonObject &item) -{ - if (item.IsNull()) { - GLOGD("Add null object."); - return E_OK; - } - - cJSON *cpoyItem = cJSON_Duplicate(item.cjson_, true); - cJSON_AddItemToObject(cjson_, item.GetItemField().c_str(), cpoyItem); - return E_OK; -} - int JsonObject::AddItemToObject(const std::string &fieldName, const JsonObject &item) { if (cjson_ == nullptr) { @@ -461,23 +438,6 @@ void JsonObject::ReplaceItemInArray(const int &index, const JsonObject &newItem, } } -void JsonObject::SetItemValue(const ValueObject &value) const -{ - if (cjson_ == nullptr) { - return; - } - switch (value.GetValueType()) { - case ValueObject::ValueType::VALUE_NUMBER: - cJSON_SetNumberValue(cjson_, value.GetDoubleValue()); - break; - case ValueObject::ValueType::VALUE_STRING: - cJSON_SetValuestring(cjson_, value.GetStringValue().c_str()); - break; - default: - break; - } -} - int JsonObject::InsertItemObject(int which, const JsonObject &newItem) { if (cjson_ == nullptr) { @@ -663,38 +623,6 @@ ValueObject JsonObject::GetObjectByPath(const JsonFieldPath &jsonPath, int &errC return objGot.GetItemValue(); } -int JsonObject::DeleteItemOnTarget(const JsonFieldPath &path) -{ - if (path.empty()) { - return -E_INVALID_ARGS; - } - - std::string fieldName = path.back(); - JsonFieldPath patherPath = path; - patherPath.pop_back(); - - cJSON *nodeFather = MoveToPath(cjson_, patherPath, caseSensitive_); - if (nodeFather == nullptr) { - return -E_JSON_PATH_NOT_EXISTS; - } - - if (nodeFather->type == cJSON_Object) { - if (caseSensitive_) { - cJSON_DeleteItemFromObjectCaseSensitive(nodeFather, fieldName.c_str()); - } else { - cJSON_DeleteItemFromObject(nodeFather, fieldName.c_str()); - } - } else if (nodeFather->type == cJSON_Array) { - if (!IsNumber(fieldName)) { - GLOGW("Invalid json field path, expect array index."); - return -E_JSON_PATH_NOT_EXISTS; - } - cJSON_DeleteItemFromArray(nodeFather, std::stoi(fieldName)); - } - - return E_OK; -} - int JsonObject::DeleteItemDeeplyOnTarget(const JsonFieldPath &path) { if (path.empty()) { diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp index d038491f..79cbcc86 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp @@ -63,7 +63,6 @@ int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, goto END; } } - executor = sqliteExecutor; return E_OK; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp index 1de43e0d..39f34788 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp @@ -18,10 +18,12 @@ #include "check_common.h" #include "db_constant.h" #include "doc_errno.h" +#include "document_key.h" #include "log_print.h" #include "sqlite_utils.h" namespace DocumentDB { +constexpr const uint8_t KEY_TYPE = uint8_t(DocIdType::STRING); int SqliteStoreExecutorImpl::CreateDatabase(const std::string &path, const DBConfig &config, sqlite3 *&db) { if (db != nullptr) { @@ -74,7 +76,7 @@ int SqliteStoreExecutorImpl::GetDBConfig(std::string &config) std::string dbConfigKeyStr = "DB_CONFIG"; Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; Value dbConfigVal; - int errCode = GetData("grd_meta", dbConfigKey, dbConfigVal); + int errCode = GetDataByKey("grd_meta", dbConfigKey, dbConfigVal); config.assign(dbConfigVal.begin(), dbConfigVal.end()); return errCode; } @@ -84,7 +86,7 @@ int SqliteStoreExecutorImpl::SetDBConfig(const std::string &config) std::string dbConfigKeyStr = "DB_CONFIG"; Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; Value dbConfigVal = { config.begin(), config.end() }; - return PutData("grd_meta", dbConfigKey, dbConfigVal); + return PutData("grd_meta", dbConfigKey, dbConfigVal, false); // dont need to add Key type; } int SqliteStoreExecutorImpl::StartTransaction() @@ -102,11 +104,14 @@ int SqliteStoreExecutorImpl::Rollback() return SQLiteUtils::RollbackTransaction(dbHandle_); } -int SqliteStoreExecutorImpl::PutData(const std::string &collName, const Key &key, const Value &value) +int SqliteStoreExecutorImpl::PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType) { if (dbHandle_ == nullptr) { return -E_ERROR; } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } std::string sql = "INSERT OR REPLACE INTO '" + collName + "' VALUES (?,?);"; int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, @@ -127,11 +132,15 @@ int SqliteStoreExecutorImpl::PutData(const std::string &collName, const Key &key return E_OK; } -int SqliteStoreExecutorImpl::InsertData(const std::string &collName, const Key &key, const Value &value) +int SqliteStoreExecutorImpl::InsertData(const std::string &collName, Key &key, const Value &value, + bool isNeedAddKeyType) { if (dbHandle_ == nullptr) { return -E_ERROR; } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } std::string sql = "INSERT INTO '" + collName + "' VALUES (?,?);"; int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, @@ -152,7 +161,7 @@ int SqliteStoreExecutorImpl::InsertData(const std::string &collName, const Key & return E_OK; } -int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key, Value &value) const +int SqliteStoreExecutorImpl::GetDataByKey(const std::string &collName, Key &key, Value &value) const { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); @@ -166,7 +175,7 @@ int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key SQLiteUtils::BindBlobToStatement(stmt, 1, key); return E_OK; }, - [&value, &innerErrorCode](sqlite3_stmt *stmt) { + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { SQLiteUtils::GetColumnBlobValue(stmt, 0, value); innerErrorCode = E_OK; return E_OK; @@ -178,8 +187,57 @@ int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key return innerErrorCode; } -int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const +int SqliteStoreExecutorImpl::GetDataById(const std::string &collName, Key &key, Value &value) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + key.push_back(KEY_TYPE); // Stitching ID type + int innerErrorCode = -E_NOT_FOUND; + std::string sql = "SELECT value FROM '" + collName + "' WHERE key=?;"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + return E_OK; + }, + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { + SQLiteUtils::GetColumnBlobValue(stmt, 0, value); + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + return innerErrorCode; +} + +std::string GeneralInsertSql(const std::string &collName, Key &key, int isIdExist) +{ + std::string sqlEqual = "SELECT key, value FROM '" + collName + "' WHERE key=?;"; + std::string sqlOrder = "SELECT key, value FROM '" + collName + "' ORDER BY KEY;"; + std::string sqlLarger = "SELECT key, value FROM '" + collName + "' WHERE key>?;"; + if (isIdExist) { + return sqlEqual; + } else { + return (key.empty()) ? sqlOrder : sqlLarger; + } +} + +void AssignValueToData(std::string &keyStr, std::string &valueStr, std::pair &values, + int &innerErrorCode, bool &isMatchOneData) +{ + keyStr.pop_back(); // get id from really key. + values.first = keyStr; + values.second = valueStr; + innerErrorCode = E_OK; + isMatchOneData = true; // this args work in ExecSql fuction +} + +int SqliteStoreExecutorImpl::GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); @@ -189,26 +247,32 @@ int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const J Value valueResult; bool isFindMatch = false; int innerErrorCode = -E_NOT_FOUND; - std::string sql = "SELECT key, value FROM '" + collName + "'ORDER BY KEY;"; + std::string sql = GeneralInsertSql(collName, key, isIdExist); + key.push_back(KEY_TYPE); + std::string keyStr(key.begin(), key.end()); int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, - [](sqlite3_stmt *stmt) { + [key](sqlite3_stmt *stmt) { + if (!key.empty()) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + } return E_OK; }, - [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt) { + [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt, + bool &isMatchOneData) { SQLiteUtils::GetColumnBlobValue(stmt, 0, keyResult); SQLiteUtils::GetColumnBlobValue(stmt, 1, valueResult); std::string keyStr(keyResult.begin(), keyResult.end()); std::string valueStr(valueResult.begin(), valueResult.end()); - int externErrCode; - JsonObject srcObj = JsonObject::Parse(valueStr, externErrCode, true); - if (externErrCode != E_OK) { + JsonObject srcObj = JsonObject::Parse(valueStr, innerErrorCode, true); + if (innerErrorCode != E_OK) { GLOGE("srcObj Parsed failed"); - return externErrCode; + return innerErrorCode; } - if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, externErrCode)) { - isFindMatch = true; - values.emplace_back(std::pair(keyStr, valueStr)); + if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, innerErrorCode)) { + isFindMatch = true; // this args work in this function + (void)AssignValueToData(keyStr, valueStr, values, innerErrorCode, isMatchOneData); + return E_OK; // match count; } innerErrorCode = E_OK; return E_OK; @@ -223,15 +287,16 @@ int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const J return innerErrorCode; } -int SqliteStoreExecutorImpl::DelData(const std::string &collName, const Key &key) +int SqliteStoreExecutorImpl::DelData(const std::string &collName, Key &key) { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); return -E_ERROR; } + key.push_back(KEY_TYPE); int errCode = 0; Value valueRet; - if (GetData(collName, key, valueRet) != E_OK) { + if (GetDataByKey(collName, key, valueRet) != E_OK) { return -E_NO_DATA; } std::string sql = "DELETE FROM '" + collName + "' WHERE key=?;"; @@ -320,7 +385,7 @@ bool SqliteStoreExecutorImpl::IsCollectionExists(const std::string &name, int &e SQLiteUtils::BindTextToStatement(stmt, 1, name); return E_OK; }, - [&isExists](sqlite3_stmt *stmt) { + [&isExists](sqlite3_stmt *stmt, bool &isMatchOneData) { isExists = true; return E_OK; }); @@ -330,22 +395,12 @@ bool SqliteStoreExecutorImpl::IsCollectionExists(const std::string &name, int &e return isExists; } -int SqliteStoreExecutorImpl::GetCollectionOption(const std::string &name, std::string &option) -{ - std::string collOptKeyStr = "COLLECTION_OPTION_" + name; - Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; - Value collOptVal; - int errCode = GetData("grd_meta", collOptKey, collOptVal); - option.assign(collOptVal.begin(), collOptVal.end()); - return errCode; -} - int SqliteStoreExecutorImpl::SetCollectionOption(const std::string &name, const std::string &option) { std::string collOptKeyStr = "COLLECTION_OPTION_" + name; Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; Value collOptVal = { option.begin(), option.end() }; - return PutData("grd_meta", collOptKey, collOptVal); + return PutData("grd_meta", collOptKey, collOptVal, false); // dont need to add key type; } int SqliteStoreExecutorImpl::CleanCollectionOption(const std::string &name) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h index 7b82379e..8da9ed30 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h @@ -37,18 +37,18 @@ public: int Commit() override; int Rollback() override; - int PutData(const std::string &collName, const Key &key, const Value &value) override; - int InsertData(const std::string &collName, const Key &key, const Value &value) override; - int GetData(const std::string &collName, const Key &key, Value &value) const override; - int GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const override; - int DelData(const std::string &collName, const Key &key) override; + int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int GetDataByKey(const std::string &collName, Key &key, Value &value) const override; + int GetDataById(const std::string &collName, Key &key, Value &value) const override; + int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const override; + int DelData(const std::string &collName, Key &key) override; int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) override; int DropCollection(const std::string &name, bool ignoreNonExists) override; bool IsCollectionExists(const std::string &name, int &errCode) override; - int GetCollectionOption(const std::string &name, std::string &option) override; int SetCollectionOption(const std::string &name, const std::string &option) override; int CleanCollectionOption(const std::string &name) override; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp index ca7332f3..2c56227d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp @@ -21,7 +21,6 @@ namespace DocumentDB { const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit -const int MAX_TEXT_READ_SIZE = 5 * 1024 * 1024; // 5M limit const int BUSY_TIMEOUT_MS = 3000; // 3000ms for sqlite busy timeout. const std::string BEGIN_SQL = "BEGIN TRANSACTION"; const std::string BEGIN_IMMEDIATE_SQL = "BEGIN IMMEDIATE TRANSACTION"; @@ -36,6 +35,7 @@ int MapSqliteError(int errCode) return E_OK; case SQLITE_PERM: case SQLITE_CANTOPEN: + return -E_INVALID_ARGS; case SQLITE_READONLY: return -E_FILE_OPERATION; case SQLITE_NOTADB: @@ -162,10 +162,6 @@ int SQLiteUtils::BindBlobToStatement(sqlite3_stmt *statement, int index, const s errCode = sqlite3_bind_blob(statement, index, static_cast(value.data()), value.size(), SQLITE_TRANSIENT); } - - if (errCode != SQLITE_OK) { - GLOGE("[SQLiteUtil][Bind blob] Failed to bind the value:%d", errCode); - } return errCode; } @@ -208,29 +204,6 @@ int SQLiteUtils::BindTextToStatement(sqlite3_stmt *statement, int index, const s return E_OK; } -int SQLiteUtils::GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value) -{ - if (statement == nullptr) { - return -E_INVALID_ARGS; - } - - int valSize = sqlite3_column_bytes(statement, index); - if (valSize < 0 || valSize > MAX_TEXT_READ_SIZE) { - GLOGW("[SQLiteUtils][Column text] size over limit:%d", valSize); - value.resize(MAX_TEXT_READ_SIZE + 1); // Reset value size to invalid - return E_OK; // Return OK for continue get data, but value is invalid - } - - const unsigned char *val = sqlite3_column_text(statement, index); - if (valSize == 0 || val == nullptr) { - value = {}; - } else { - value = std::string(reinterpret_cast(val)); - } - - return E_OK; -} - int SQLiteUtils::BeginTransaction(sqlite3 *db, TransactType type) { if (type == TransactType::IMMEDIATE) { @@ -267,18 +240,18 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql) } int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback) + const std::function &resultCallback) { if (db == nullptr || sql.empty()) { return -E_INVALID_ARGS; } bool bindFinish = true; sqlite3_stmt *stmt = nullptr; + bool isMatchOneData = false; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { goto END; } - do { if (bindCallback) { errCode = bindCallback(stmt); @@ -295,10 +268,10 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::functio } else if (errCode != SQLITE_ROW) { goto END; // Step return error } - if (resultCallback != nullptr) { - errCode = resultCallback(stmt); + if (resultCallback != nullptr) { // find one data, stop stepping. + errCode = resultCallback(stmt, isMatchOneData); } - if (resultCallback != nullptr && errCode != E_OK) { + if (resultCallback != nullptr && ((errCode != E_OK) || isMatchOneData)) { goto END; } } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h index 3567163c..88cc77ef 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h @@ -40,7 +40,6 @@ public: static int GetColumnBlobValue(sqlite3_stmt *statement, int index, std::vector &value); static int BindTextToStatement(sqlite3_stmt *statement, int index, const std::string &value); - static int GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value); static int BeginTransaction(sqlite3 *db, TransactType type = TransactType::DEFERRED); static int CommitTransaction(sqlite3 *db); @@ -48,7 +47,7 @@ public: static int ExecSql(sqlite3 *db, const std::string &sql); static int ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback); + const std::function &resultCallback); private: static void SqliteLogCallback(void *data, int err, const char *msg); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn index 81eb4698..c8a7cab5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn @@ -57,6 +57,7 @@ ohos_source_set("src_file") { "../../src/executor/document/grd_resultset_api.cpp", "../../src/interface/src/collection.cpp", "../../src/interface/src/doc_errno.cpp", + "../../src/interface/src/document_key.cpp", "../../src/interface/src/document_store.cpp", "../../src/interface/src/document_store_manager.cpp", "../../src/interface/src/projection_tree.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp index 22fe15ee..820667f7 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp @@ -16,6 +16,7 @@ #include #include "doc_errno.h" +#include "doc_limit.h" #include "documentdb_test_utils.h" #include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" @@ -156,7 +157,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest004, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBPathTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::vector invalidPath = { nullptr, "", "/a/b/c/" }; + std::vector invalidPath = { nullptr, "" }; for (auto path : invalidPath) { GLOGD("OpenDBPathTest001: open db with path: %s", path); int status = GRD_DBOpen(path, nullptr, GRD_DB_OPEN_CREATE, &db); @@ -179,6 +180,21 @@ HWTEST_F(DocumentDBApiTest, OpenDBPathTest002, TestSize.Level0) EXPECT_EQ(status, GRD_FAILED_FILE_OPERATION); } +/** + * @tc.name: OpenDBPathTest004 + * @tc.desc: call GRD_DBOpen, input dbFile as existed menu + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBPathTest004, TestSize.Level0) +{ + GRD_DB *db = nullptr; + std::string pathNoPerm = "../test"; + int status = GRD_DBOpen(pathNoPerm.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); +} + /** * @tc.name: OpenDBConfigTest001 * @tc.desc: Test open document db with invalid config option @@ -190,7 +206,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest001, TestSize.Level0) { GRD_DB *db = nullptr; std::string path = "./document.db"; - const int MAX_JSON_LEN = 512 * 1024; + const int MAX_JSON_LEN = 1024 * 1024; std::string configStr = std::string(MAX_JSON_LEN, 'a'); int status = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OVER_LIMIT); @@ -226,6 +242,65 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest003, TestSize.Level0) EXPECT_EQ(status, GRD_INVALID_ARGS); } +/** + * @tc.name: OpenDBConfigTest004 + * @tc.desc: call GRD_DBOpen, input the value's length of configStr is 1024K + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ + +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. input the value's length of configStr is 1024 k(not contained '\0') + */ + GRD_DB *db = nullptr; + std::string part1 = "{ \"pageSize\": \" "; + std::string part2 = "\" }"; + std::string path = "./document.db"; + std::string val = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size(), 'k'); + std::string configStr = part1 + val + part2; + int ret = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_OVER_LIMIT); + /** + * @tc.steps:step2. input the value's length of configStr is 1024 k(contained '\0') + */ + std::string val2 = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size() - 1, 'k'); + std::string configStr2 = part1 + val2 + part2 + "\0"; + ret = GRD_DBOpen(path.c_str(), configStr2.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_INVALID_ARGS); +} + +/** + * @tc.name: OpenDBConfigTest005 + * @tc.desc: Verify open db with different configStr connection when first connection not close, + * return GRD_INVALID_CONFIG_VALUE. + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. call GRD_DBOPEN to create a db with connection1. + * @tc.expected:step1. GRD_OK. + */ + const char *configStr = R"({"pageSize":64, "bufferPoolSize": 4096})"; + GRD_DB *db1 = nullptr; + std::string path = "./document.db"; + int result = GRD_DBOpen(path.c_str(), configStr, GRD_DB_OPEN_CREATE, &db1); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps:step2. connection2 call GRD_DBOpen to open the db with the different configStr. + * @tc.expected:step2. return GRD_CONFIG_OPTION_MISMATCH. + */ + const char *configStr_2 = R"({"pageSize":4})"; + GRD_DB *db2 = nullptr; + result = GRD_DBOpen(path.c_str(), configStr_2, GRD_DB_OPEN_ONLY, &db2); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + ASSERT_EQ(GRD_DBClose(db1, GRD_DB_CLOSE), GRD_OK); +} /** * @tc.name: OpenDBConfigMaxConnNumTest001 * @tc.desc: Test open document db with invalid config item maxConnNum @@ -381,9 +456,8 @@ int GetDBPageSize(const std::string &path) if (db == nullptr) { return 0; } - int pageSize = 0; - SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt) { + SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt, bool &isMatchOneData) { pageSize = sqlite3_column_int(stmt, 0); return E_OK; }); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp index 7fdb5a56..129ea35b 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp @@ -32,7 +32,7 @@ namespace { std::string g_path = "./document.db"; GRD_DB *g_db = nullptr; const char *g_coll = "student"; - +constexpr int JSON_LENS_MAX = 1024 * 1024; class DocumentDBDataTest : public testing::Test { public: static void SetUpTestCase(void); @@ -133,7 +133,6 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest006, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - for (auto flags : std::vector { 2, 4, 8, 64, 1024, UINT32_MAX }) { EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), flags), GRD_INVALID_ARGS); } @@ -174,8 +173,12 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest008, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpsertDataTest009, TestSize.Level0) { std::string filter = R""({"_id":"abcde"})""; - std::string document = R"({"field1": ")" + string(1024 * 1024 + 1, 'a') + "\"}"; - EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_REPLACE), GRD_OVER_LIMIT); + std::string head = R"({"field1": ")"; + std::string document = + head + string(JSON_LENS_MAX - filter.size() - head.size() - 1, 'a') + "\"}"; // 13 is {"field1": size + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_APPEND), 1); + std::string document2 = head + string(JSON_LENS_MAX - filter.size() - head.size(), 'a') + "\"}"; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document2.c_str(), GRD_DOC_REPLACE), GRD_OVER_LIMIT); } HWTEST_F(DocumentDBDataTest, UpsertDataTest010, TestSize.Level0) @@ -191,6 +194,32 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest011, TestSize.Level0) ASSERT_EQ(result, GRD_INVALID_FORMAT); } +/** + * @tc.name: UpdateDataTest012 + * @tc.desc: Input parameter collectionName is null, invoke the GRD_UpsertDoc interface to update data. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest012, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert a document. + * @tc.expected: step1. return GRD_OK. + */ + int result = GRD_InsertDoc(g_db, g_coll, "{}", 0); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps: step2. Parameter collectionName is Invalid format + * @tc.expected: step2. return Update faild. + */ + result = GRD_UpsertDoc(g_db, "null", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + result = GRD_UpsertDoc(g_db, "!! &%$^%$&*%^。m中文、、请问E:112423123", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); +} + /** * @tc.name: UpdateDataTest001 * @tc.desc: @@ -244,24 +273,6 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest003, TestSize.Level0) } } -/** - * @tc.name: UpdateDataTest004 - * @tc.desc: Test update data with invalid filter - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpdateDataTest004, TestSize.Level0) {} - -/** - * @tc.name: UpdateDataTest005 - * @tc.desc: Test update data with invalid doc - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpdateDataTest005, TestSize.Level0) {} - /** * @tc.name: UpdateDataTest006 * @tc.desc: Test update data with invalid flag @@ -303,11 +314,11 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest008, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpdateDataTest009, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; - std::string document = R""({"_id":"1234", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2" : 2})""; + std::string document = R""({"_id":"1234","field1":{"c_field":{"cc_field":{"ccc_field":1}}},"field2":2})""; EXPECT_EQ(GRD_InsertDoc(g_db, g_coll, document.c_str(), 0), GRD_OK); - std::string updata = R""({"field1":1, "FIELD1":[1, true, 1.23456789, "hello world!", null]})""; + std::string updata = R""({"field1":1,"FIELD1":[1,true,1.23456789,"hello world!",null]})""; EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), updata.c_str(), 0), 1); GRD_ResultSet *resultSet = nullptr; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp index 7ce58327..8e862bb6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp @@ -824,6 +824,12 @@ HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest045, TestSize.Level1) HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest046, TestSize.Level1) { const char *document1 = R""({})""; - EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest047, TestSize.Level1) +{ + const char *document1 = "{\"empty\" : null}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); } } // namespace diff --git a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp index 3e92ba17..ff4820e9 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -590,19 +590,4 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest023, TestSize.Leve EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj1, errCode), true); EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj1, errCode), false); } - -HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest024, TestSize.Level0) -{ - std::string document = "{\"name\": 1, \"personInfo.school\": 1, \"personInfo.age\": 1}"; - int errCode = E_OK; - JsonObject srcObj = JsonObject::Parse(document, errCode); - EXPECT_EQ(errCode, E_OK); - auto path = JsonCommon::ParsePath(srcObj, errCode); - for (auto singlePath : path) { - for (auto fieldName : singlePath) { - GLOGE("fieldName is =========>%s", fieldName.c_str()); - } - GLOGE("///////////////////////////"); - } -} } // namespace \ No newline at end of file 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 27f2780a..f8595c73 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 @@ -64,7 +64,8 @@ bool LoadConfigFromDataProxyNodeStrategy::operator()(std::shared_ptr co ZLOGI("access private data, caller and called is same, go"); return true; } - if (context->isAllowCrossPer) { + // cross permission can only cross uri like weather,can not cross like datashareproxy://weather + if (context->isAllowCrossPer && !URIUtils::IsDataProxyURI(context->uri)) { ZLOGI("access has white permission, go"); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp index fd1f8d93..859bc436 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp @@ -33,6 +33,7 @@ bool LoadConfigCommonStrategy::operator()(std::shared_ptr context) if (context->currentUserId == 0) { URIUtils::GetInfoFromProxyURI( context->uri, context->currentUserId, context->callerTokenId, context->calledBundleName); + FormatUri(context->uri); } if (context->needAutoLoadCallerBundleName && context->callerBundleName.empty()) { Security::AccessToken::HapTokenInfo tokenInfo; @@ -43,13 +44,12 @@ bool LoadConfigCommonStrategy::operator()(std::shared_ptr context) } context->callerBundleName = tokenInfo.bundleName; } - FormatUri(context->uri); return true; } void LoadConfigCommonStrategy::FormatUri(std::string &uri) { - auto pos = uri.find('?'); + auto pos = uri.find_last_of('?'); if (pos == std::string::npos) { return; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp index 2df8047a..c32d5daf 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/get_data_strategy.cpp @@ -38,7 +38,7 @@ Data GetDataStrategy::Execute(std::shared_ptr context, int &errorCode) } auto result = PublishedData::Query(context->calledBundleName, context->currentUserId); Data data; - for (const auto &item:result) { + for (auto &item : result) { if (!CheckPermission(context, item.value.key)) { ZLOGI("uri: %{private}s not allowed", context->uri.c_str()); continue; @@ -46,7 +46,8 @@ Data GetDataStrategy::Execute(std::shared_ptr context, int &errorCode) if (item.GetVersion() > data.version_) { data.version_ = item.GetVersion(); } - data.datas_.emplace_back(item.value.key, item.value.subscriberId, item.value.value); + data.datas_.emplace_back( + item.value.key, item.value.subscriberId, PublishedDataNode::MoveTo(item.value.value)); } return data; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp index 5c785f9e..ca17e44a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/publish_strategy.cpp @@ -41,8 +41,9 @@ int32_t PublishStrategy::Execute(std::shared_ptr context, const Publish ZLOGE("db open failed"); return -1; } - PublishedDataNode node( - context->uri, context->calledBundleName, item.subscriberId_, context->currentUserId, item.GetData()); + PublishedDataItem::DataType value = item.GetData(); + PublishedDataNode node(context->uri, context->calledBundleName, item.subscriberId_, context->currentUserId, + PublishedDataNode::MoveTo(value)); PublishedData data(node, context->version); int32_t status = delegate->Upsert(KvDBDelegate::DATA_TABLE, data); if (status != E_OK) { diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp index 52cb9816..4502f670 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/rdb_notify_strategy.cpp @@ -35,7 +35,7 @@ bool RdbNotifyStrategy::Execute(std::shared_ptr context) return false; } if (context->callerBundleName != context->calledBundleName) { - ZLOGE("not your data, cannot notify, callerBundleName: %{public}s, calledBundleName: %{public}s", + ZLOGD("not your data, cannot notify, callerBundleName: %{public}s, calledBundleName: %{public}s", context->callerBundleName.c_str(), context->calledBundleName.c_str()); return false; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp index af1570d4..a2ad08c8 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp @@ -16,6 +16,7 @@ #include "published_data_subscriber_manager.h" +#include "ipc_skeleton.h" #include "general/load_config_data_info_strategy.h" #include "log_print.h" #include "published_data.h" @@ -29,59 +30,28 @@ PublishedDataSubscriberManager &PublishedDataSubscriberManager::GetInstance() return manager; } -void PublishedDataSubscriberManager::LinkToDeath( - const PublishedDataKey &key, sptr observer) -{ - sptr deathRecipient = new (std::nothrow) ObserverNodeRecipient(this, key, observer); - if (deathRecipient == nullptr) { - ZLOGE("new ObserverNodeRecipient error. uri is %{public}s", - DistributedData::Anonymous::Change(key.key).c_str()); - return; - } - auto remote = observer->AsObject(); - if (!remote->AddDeathRecipient(deathRecipient)) { - ZLOGE("add death recipient failed, uri is %{public}s", DistributedData::Anonymous::Change(key.key).c_str()); - return; - } - ZLOGD("link to death success, uri is %{public}s", DistributedData::Anonymous::Change(key.key).c_str()); -} - -void PublishedDataSubscriberManager::OnRemoteDied( - const PublishedDataKey &key, sptr observer) -{ - publishedDataCache.ComputeIfPresent(key, [&observer, this](const auto &key, std::vector &value) { - for (auto it = value.begin(); it != value.end(); ++it) { - if (it->observer->AsObject() == observer->AsObject()) { - value.erase(it); - ZLOGI("OnRemoteDied delete subscriber, uri is %{public}s", - DistributedData::Anonymous::Change(key.key).c_str()); - break; - } - } - return !value.empty(); - }); -} int PublishedDataSubscriberManager::Add( - const PublishedDataKey &key, const sptr observer, const uint32_t callerTokenId) + const PublishedDataKey &key, const sptr observer, uint32_t firstCallerTokenId) { - publishedDataCache.Compute( - key, [&observer, &callerTokenId, this](const PublishedDataKey &key, std::vector &value) { - ZLOGI("add publish subscriber, uri %{private}s tokenId %{public}d", key.key.c_str(), callerTokenId); - LinkToDeath(key, observer); - value.emplace_back(observer, callerTokenId); + publishedDataCache_.Compute( + key, [&observer, &firstCallerTokenId, this](const PublishedDataKey &key, std::vector &value) { + ZLOGI("add publish subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), firstCallerTokenId); + value.emplace_back(observer, firstCallerTokenId, IPCSkeleton::GetCallingTokenID()); return true; }); return E_OK; } -int PublishedDataSubscriberManager::Delete(const PublishedDataKey &key, const uint32_t callerTokenId) +int PublishedDataSubscriberManager::Delete(const PublishedDataKey &key, uint32_t firstCallerTokenId) { auto result = - publishedDataCache.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + publishedDataCache_.ComputeIfPresent(key, [&firstCallerTokenId](const auto &key, + std::vector &value) { for (auto it = value.begin(); it != value.end();) { - if (it->callerTokenId == callerTokenId) { - ZLOGI("delete publish subscriber, uri %{private}s tokenId %{public}d", key.key.c_str(), - callerTokenId); + if (it->firstCallerTokenId == firstCallerTokenId) { + ZLOGI("delete publish subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), firstCallerTokenId); it = value.erase(it); } else { it++; @@ -92,13 +62,31 @@ int PublishedDataSubscriberManager::Delete(const PublishedDataKey &key, const ui return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -int PublishedDataSubscriberManager::Disable(const PublishedDataKey &key, const uint32_t callerTokenId) +void PublishedDataSubscriberManager::Delete(uint32_t callerTokenId) +{ + publishedDataCache_.EraseIf([&callerTokenId](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("erase start, uri is %{public}s, tokenId is 0x%{public}x", + DistributedData::Anonymous::Change(key.key).c_str(), callerTokenId); + it = value.erase(it); + } else { + it++; + } + } + return value.empty(); + }); +} + +int PublishedDataSubscriberManager::Disable(const PublishedDataKey &key, uint32_t firstCallerTokenId) { auto result = - publishedDataCache.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + publishedDataCache_.ComputeIfPresent(key, [&firstCallerTokenId](const auto &key, + std::vector &value) { for (auto it = value.begin(); it != value.end(); it++) { - if (it->callerTokenId == callerTokenId) { + if (it->firstCallerTokenId == firstCallerTokenId) { it->enabled = false; + it->isNotifyOnEnabled = false; } } return true; @@ -106,12 +94,13 @@ int PublishedDataSubscriberManager::Disable(const PublishedDataKey &key, const u return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -int PublishedDataSubscriberManager::Enable(const PublishedDataKey &key, const uint32_t callerTokenId) +int PublishedDataSubscriberManager::Enable(const PublishedDataKey &key, uint32_t firstCallerTokenId) { auto result = - publishedDataCache.ComputeIfPresent(key, [&callerTokenId](const auto &key, std::vector &value) { + publishedDataCache_.ComputeIfPresent(key, [&firstCallerTokenId](const auto &key, + std::vector &value) { for (auto it = value.begin(); it != value.end(); it++) { - if (it->callerTokenId == callerTokenId) { + if (it->firstCallerTokenId == firstCallerTokenId) { it->enabled = true; } } @@ -120,14 +109,14 @@ int PublishedDataSubscriberManager::Enable(const PublishedDataKey &key, const ui return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -void PublishedDataSubscriberManager::Emit(const std::vector &keys, const int32_t userId, +void PublishedDataSubscriberManager::Emit(const std::vector &keys, int32_t userId, const std::string &ownerBundleName, const sptr observer) { int32_t status; // key is bundleName, value is change node std::map publishedResult; std::map, std::vector> callbacks; - publishedDataCache.ForEach([&keys, &status, &observer, &publishedResult, &callbacks, &userId, this]( + publishedDataCache_.ForEach([&keys, &status, &observer, &publishedResult, &callbacks, &userId, this]( const PublishedDataKey &key, std::vector &val) { for (auto &data : keys) { if (key != data || publishedResult.count(key) != 0) { @@ -151,7 +140,7 @@ void PublishedDataSubscriberManager::Emit(const std::vector &k result.datas_.clear(); for (auto &key : keys) { if (publishedResult.count(key) != 0) { - result.datas_.emplace_back(key.key, key.subscriberId, publishedResult[key]); + result.datas_.emplace_back(key.key, key.subscriberId, PublishedDataNode::MoveTo(publishedResult[key])); } } if (result.datas_.empty()) { @@ -180,19 +169,47 @@ void PublishedDataSubscriberManager::PutInto( void PublishedDataSubscriberManager::Clear() { - publishedDataCache.Clear(); + publishedDataCache_.Clear(); } int PublishedDataSubscriberManager::GetCount(const PublishedDataKey &key) { int count = 0; - publishedDataCache.ComputeIfPresent(key, [&count](const auto &key, std::vector &value) { - count = value.size(); + publishedDataCache_.ComputeIfPresent(key, [&count](const auto &key, std::vector &value) { + count = static_cast(value.size()); return true; }); return count; } +bool PublishedDataSubscriberManager::IsNotifyOnEnabled(const PublishedDataKey &key, uint32_t callerTokenId) +{ + auto pair = publishedDataCache_.Find(key); + if (!pair.first) { + return false; + } + for (const auto &value : pair.second) { + if (value.firstCallerTokenId == callerTokenId && value.isNotifyOnEnabled) { + return true; + } + } + return false; +} + +void PublishedDataSubscriberManager::SetObserversNotifiedOnEnabled(const std::vector &keys) +{ + for (const auto &pkey : keys) { + publishedDataCache_.ComputeIfPresent(pkey, [](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end(); it++) { + if (!it->enabled) { + it->isNotifyOnEnabled = true; + } + } + return true; + }); + } +} + PublishedDataKey::PublishedDataKey(const std::string &key, const std::string &bundle, const int64_t subscriberId) : key(key), bundleName(bundle), subscriberId(subscriberId) { @@ -246,9 +263,9 @@ bool PublishedDataKey::operator!=(const PublishedDataKey &rhs) const return !(rhs == *this); } -PublishedDataSubscriberManager::ObserverNode::ObserverNode( - const sptr &observer, uint32_t callerTokenId) - : observer(observer), callerTokenId(callerTokenId) +PublishedDataSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, + uint32_t firstCallerTokenId, uint32_t callerTokenId) + : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId) { } } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h index de3149d2..60cfecdc 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/published_data_subscriber_manager.h @@ -26,7 +26,7 @@ #include "executor_pool.h" namespace OHOS::DataShare { struct PublishedDataKey { - PublishedDataKey(const std::string &key, const std::string &bundleName, const int64_t subscriberId); + PublishedDataKey(const std::string &key, const std::string &bundleName, int64_t subscriberId); bool operator<(const PublishedDataKey &rhs) const; bool operator>(const PublishedDataKey &rhs) const; bool operator<=(const PublishedDataKey &rhs) const; @@ -42,46 +42,34 @@ class PublishedDataSubscriberManager { public: static PublishedDataSubscriberManager &GetInstance(); int Add(const PublishedDataKey &key, const sptr observer, - const uint32_t callerTokenId); - int Delete(const PublishedDataKey &key, const uint32_t callerTokenId); - int Disable(const PublishedDataKey &key, const uint32_t callerTokenId); - int Enable(const PublishedDataKey &key, const uint32_t callerTokenId); - void Emit(const std::vector &keys, const int32_t userId, const std::string &ownerBundleName, + uint32_t firstCallerTokenId); + int Delete(const PublishedDataKey &key, uint32_t firstCallerTokenId); + void Delete(uint32_t callerTokenId); + int Disable(const PublishedDataKey &key, uint32_t firstCallerTokenId); + int Enable(const PublishedDataKey &key, uint32_t firstCallerTokenId); + void Emit(const std::vector &keys, int32_t userId, const std::string &ownerBundleName, const sptr observer = nullptr); void Clear(); int GetCount(const PublishedDataKey &key); + + bool IsNotifyOnEnabled(const PublishedDataKey &key, uint32_t callerTokenId); + void SetObserversNotifiedOnEnabled(const std::vector &keys); + private: struct ObserverNode { - ObserverNode(const sptr &observer, uint32_t callerTokenId); + ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, + uint32_t callerTokenId = 0); sptr observer; + uint32_t firstCallerTokenId; uint32_t callerTokenId; bool enabled = true; + bool isNotifyOnEnabled = false; }; - class ObserverNodeRecipient : public IRemoteObject::DeathRecipient { - public: - ObserverNodeRecipient(PublishedDataSubscriberManager *owner, const PublishedDataKey &key, - sptr observer) : owner_(owner), key_(key), observer_(observer) {}; - - void OnRemoteDied(const wptr &object) override - { - if (owner_ != nullptr) { - owner_->OnRemoteDied(key_, observer_); - } - } - - private: - PublishedDataSubscriberManager *owner_; - PublishedDataKey key_; - sptr observer_; - }; - - void LinkToDeath(const PublishedDataKey &key, sptr observer); - void OnRemoteDied(const PublishedDataKey &key, sptr observer); PublishedDataSubscriberManager() = default; void PutInto(std::map, std::vector> &, const std::vector &, const PublishedDataKey &, const sptr); - ConcurrentMap> publishedDataCache; + ConcurrentMap> publishedDataCache_; }; } // namespace OHOS::DataShare #endif 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 faf0cb57..10411c55 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 @@ -16,6 +16,7 @@ #include "rdb_subscriber_manager.h" +#include "ipc_skeleton.h" #include "general/load_config_data_info_strategy.h" #include "log_print.h" #include "scheduler_manager.h" @@ -24,12 +25,12 @@ #include "utils/anonymous.h" namespace OHOS::DataShare { -bool TemplateManager::Get(const Key &key, const int32_t userId, Template &tpl) +bool TemplateManager::Get(const Key &key, int32_t userId, Template &tpl) { return TemplateData::Query(Id(TemplateData::GenId(key.uri, key.bundleName, key.subscriberId), userId), tpl) == E_OK; } -int32_t TemplateManager::Add(const Key &key, const int32_t userId, const Template &tpl) +int32_t TemplateManager::Add(const Key &key, int32_t userId, const Template &tpl) { auto status = TemplateData::Add(key.uri, userId, key.bundleName, key.subscriberId, tpl); if (!status) { @@ -39,7 +40,7 @@ int32_t TemplateManager::Add(const Key &key, const int32_t userId, const Templat return E_OK; } -int32_t TemplateManager::Delete(const Key &key, const int32_t userId) +int32_t TemplateManager::Delete(const Key &key, int32_t userId) { auto status = TemplateData::Delete(key.uri, userId, key.bundleName, key.subscriberId); if (!status) { @@ -50,7 +51,7 @@ int32_t TemplateManager::Delete(const Key &key, const int32_t userId) return E_OK; } -Key::Key(const std::string &uri, const int64_t subscriberId, const std::string &bundleName) +Key::Key(const std::string &uri, int64_t subscriberId, const std::string &bundleName) : uri(uri), subscriberId(subscriberId), bundleName(bundleName) { } @@ -107,72 +108,44 @@ RdbSubscriberManager &RdbSubscriberManager::GetInstance() return manager; } -void RdbSubscriberManager::LinkToDeath(const Key &key, sptr observer) -{ - sptr deathRecipient = new (std::nothrow) ObserverNodeRecipient(this, key, observer); - if (deathRecipient == nullptr) { - ZLOGE("new ObserverNodeRecipient error, uri is %{public}s", - DistributedData::Anonymous::Change(key.uri).c_str()); - return; - } - auto remote = observer->AsObject(); - if (!remote->AddDeathRecipient(deathRecipient)) { - ZLOGE("add death recipient failed, uri is %{public}s", DistributedData::Anonymous::Change(key.uri).c_str()); - return; - } - ZLOGD("link to death success, uri is %{public}s", DistributedData::Anonymous::Change(key.uri).c_str()); -} - -void RdbSubscriberManager::OnRemoteDied(const Key &key, sptr observer) -{ - rdbCache_.ComputeIfPresent(key, [&observer, this](const auto &key, std::vector &value) { - for (auto it = value.begin(); it != value.end(); ++it) { - if (it->observer->AsObject() == observer->AsObject()) { - value.erase(it); - ZLOGI("OnRemoteDied delete subscriber, uri is %{public}s", - DistributedData::Anonymous::Change(key.uri).c_str()); - break; - } - } - if (GetEnableObserverCount(key) == 0) { - SchedulerManager::GetInstance().RemoveTimer(key); - } - return !value.empty(); - }); -} int RdbSubscriberManager::Add(const Key &key, const sptr observer, std::shared_ptr context, std::shared_ptr executorPool) { int result = E_OK; rdbCache_.Compute(key, [&observer, &context, executorPool, this](const auto &key, auto &value) { - ZLOGI("add subscriber, uri %{private}s tokenId %{public}d", key.uri.c_str(), context->callerTokenId); + ZLOGI("add subscriber, uri %{private}s tokenId 0x%{public}x", key.uri.c_str(), context->callerTokenId); + auto callerTokenId = IPCSkeleton::GetCallingTokenID(); + value.emplace_back(observer, context->callerTokenId, callerTokenId); std::vector node; - node.emplace_back(observer, context->callerTokenId); + node.emplace_back(observer, context->callerTokenId, callerTokenId); ExecutorPool::Task task = [key, node, context, this]() { LoadConfigDataInfoStrategy loadDataInfo; - if (loadDataInfo(context)) { - Notify(key, context->currentUserId, node, context->calledSourceDir, context->version); + if (!loadDataInfo(context)) { + ZLOGE("loadDataInfo failed, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.uri).c_str(), context->callerTokenId); + return; + } + Notify(key, context->currentUserId, node, context->calledSourceDir, context->version); + if (GetEnableObserverCount(key) == 1) { + SchedulerManager::GetInstance().Execute( + key, context->currentUserId, context->calledSourceDir, context->version); } }; executorPool->Execute(task); - value.emplace_back(observer, context->callerTokenId); - LinkToDeath(key, observer); - if (GetEnableObserverCount(key) == 1) { - SchedulerManager::GetInstance().Execute( - key, context->currentUserId, context->calledSourceDir, context->version); - } return true; }); return result; } -int RdbSubscriberManager::Delete(const Key &key, const uint32_t callerTokenId) +int RdbSubscriberManager::Delete(const Key &key, uint32_t firstCallerTokenId) { auto result = - rdbCache_.ComputeIfPresent(key, [&callerTokenId, this](const auto &key, std::vector &value) { - ZLOGI("delete subscriber, uri %{private}s tokenId %{public}d", key.uri.c_str(), callerTokenId); + rdbCache_.ComputeIfPresent(key, [&firstCallerTokenId, this](const auto &key, + std::vector &value) { + ZLOGI("delete subscriber, uri %{public}s tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.uri).c_str(), firstCallerTokenId); for (auto it = value.begin(); it != value.end();) { - if (it->callerTokenId == callerTokenId) { + if (it->firstCallerTokenId == firstCallerTokenId) { ZLOGI("erase start"); it = value.erase(it); } else { @@ -187,18 +160,36 @@ int RdbSubscriberManager::Delete(const Key &key, const uint32_t callerTokenId) return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; } -int RdbSubscriberManager::Disable(const Key &key, const uint32_t callerTokenId) +void RdbSubscriberManager::Delete(uint32_t callerTokenId) +{ + rdbCache_.EraseIf([&callerTokenId, this](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId) { + ZLOGI("erase start, uri is %{public}s, tokenId 0x%{public}x", + DistributedData::Anonymous::Change(key.uri).c_str(), callerTokenId); + it = value.erase(it); + } else { + it++; + } + } + if (GetEnableObserverCount(key) == 0) { + SchedulerManager::GetInstance().RemoveTimer(key); + } + return value.empty(); + }); +} + +int RdbSubscriberManager::Disable(const Key &key, uint32_t firstCallerTokenId) { auto result = - rdbCache_.ComputeIfPresent(key, [&callerTokenId, this](const auto &key, std::vector &value) { + rdbCache_.ComputeIfPresent(key, [&firstCallerTokenId, this](const auto &key, + std::vector &value) { for (auto it = value.begin(); it != value.end(); it++) { - if (it->callerTokenId == callerTokenId) { + if (it->firstCallerTokenId == firstCallerTokenId) { it->enabled = false; + it->isNotifyOnEnabled = false; } } - if (GetEnableObserverCount(key) == 0) { - SchedulerManager::GetInstance().RemoveTimer(key); - } return true; }); return result ? E_OK : E_SUBSCRIBER_NOT_EXIST; @@ -208,8 +199,11 @@ int RdbSubscriberManager::Enable(const Key &key, std::shared_ptr contex { auto result = rdbCache_.ComputeIfPresent(key, [&context, this](const auto &key, std::vector &value) { for (auto it = value.begin(); it != value.end(); it++) { - if (it->callerTokenId == context->callerTokenId) { - it->enabled = true; + if (it->firstCallerTokenId != context->callerTokenId) { + continue; + } + it->enabled = true; + if (it->isNotifyOnEnabled) { std::vector node; node.emplace_back(it->observer, context->callerTokenId); LoadConfigDataInfoStrategy loadDataInfo; @@ -217,10 +211,6 @@ int RdbSubscriberManager::Enable(const Key &key, std::shared_ptr contex Notify(key, context->currentUserId, node, context->calledSourceDir, context->version); } } - if (GetEnableObserverCount(key) == 1) { - SchedulerManager::GetInstance().Execute( - key, context->currentUserId, context->calledSourceDir, context->version); - } } return true; }); @@ -241,8 +231,20 @@ void RdbSubscriberManager::Emit(const std::string &uri, std::shared_ptr return false; } Notify(key, context->currentUserId, val, context->calledSourceDir, context->version); + SetObserverNotifyOnEnabled(val); return false; }); + SchedulerManager::GetInstance().Execute( + uri, context->currentUserId, context->calledSourceDir, context->version); +} + +void RdbSubscriberManager::SetObserverNotifyOnEnabled(std::vector &nodes) +{ + for (auto &node : nodes) { + if (!node.enabled) { + node.isNotifyOnEnabled = true; + } + } } std::vector RdbSubscriberManager::GetKeysByUri(const std::string &uri) @@ -258,26 +260,18 @@ std::vector RdbSubscriberManager::GetKeysByUri(const std::string &uri) return results; } -void RdbSubscriberManager::EmitByKey(const Key &key, const int32_t userId, const std::string &rdbPath, int version) +void RdbSubscriberManager::EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version) { if (!URIUtils::IsDataProxyURI(key.uri)) { return; } rdbCache_.ComputeIfPresent(key, [&rdbPath, &version, &userId, this](const Key &key, auto &val) { Notify(key, userId, val, rdbPath, version); + SetObserverNotifyOnEnabled(val); return true; }); } -int RdbSubscriberManager::GetCount(const Key &key) -{ - auto pair = rdbCache_.Find(key); - if (!pair.first) { - return 0; - } - return pair.second.size(); -} - int RdbSubscriberManager::GetEnableObserverCount(const Key &key) { auto pair = rdbCache_.Find(key); @@ -293,7 +287,7 @@ int RdbSubscriberManager::GetEnableObserverCount(const Key &key) return count; } -int RdbSubscriberManager::Notify(const Key &key, const int32_t userId, const std::vector &val, +int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vector &val, const std::string &rdbDir, int rdbVersion) { Template tpl; @@ -314,6 +308,9 @@ int RdbSubscriberManager::Notify(const Key &key, const int32_t userId, const std changeNode.templateId_.bundleName_ = key.bundleName; for (const auto &predicate : tpl.predicates_) { std::string result = delegate->Query(predicate.selectSql_); + if (result.empty()) { + continue; + } changeNode.data_.emplace_back("{\"" + predicate.key_ + "\":" + result + "}"); } @@ -331,8 +328,29 @@ void RdbSubscriberManager::Clear() rdbCache_.Clear(); } -RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, uint32_t callerTokenId) - : observer(observer), callerTokenId(callerTokenId) +void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context) +{ + if (!URIUtils::IsDataProxyURI(uri)) { + return; + } + if (context->calledSourceDir.empty()) { + LoadConfigDataInfoStrategy loadDataInfo; + loadDataInfo(context); + } + rdbCache_.ForEach([&uri, &context, &subscriberId, this](const Key &key, std::vector &val) { + if (key.uri != uri || key.subscriberId != subscriberId) { + return false; + } + Notify(key, context->currentUserId, val, context->calledSourceDir, context->version); + SetObserverNotifyOnEnabled(val); + return false; + }); + SchedulerManager::GetInstance().Execute( + uri, context->currentUserId, context->calledSourceDir, context->version); +} +RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, + uint32_t firstCallerTokenId, uint32_t callerTokenId) + : observer(observer), firstCallerTokenId(firstCallerTokenId), callerTokenId(callerTokenId) { } } // namespace OHOS::DataShare \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h index f5e68d6d..5d1be58b 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h @@ -26,7 +26,7 @@ #include "executor_pool.h" namespace OHOS::DataShare { struct Key { - Key(const std::string &uri, const int64_t subscriberId, const std::string &bundleName); + Key(const std::string &uri, int64_t subscriberId, const std::string &bundleName); bool operator==(const Key &rhs) const; bool operator!=(const Key &rhs) const; bool operator<(const Key &rhs) const; @@ -40,9 +40,9 @@ struct Key { class TemplateManager { public: static TemplateManager &GetInstance(); - int32_t Add(const Key &key, const int32_t userId, const Template &tpl); - int32_t Delete(const Key &key, const int32_t userId); - bool Get(const Key &key, const int32_t userId, Template &tpl); + int32_t Add(const Key &key, int32_t userId, const Template &tpl); + int32_t Delete(const Key &key, int32_t userId); + bool Get(const Key &key, int32_t userId, Template &tpl); private: TemplateManager(); @@ -54,48 +54,33 @@ public: static RdbSubscriberManager &GetInstance(); int Add(const Key &key, const sptr observer, std::shared_ptr context, std::shared_ptr executorPool); - int Delete(const Key &key, const uint32_t callerTokenId); - int Disable(const Key &key, const uint32_t callerTokenId); + int Delete(const Key &key, uint32_t firstCallerTokenId); + void Delete(uint32_t callerTokenId); + int Disable(const Key &key, uint32_t firstCallerTokenId); int Enable(const Key &key, std::shared_ptr context); + void Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context); void Emit(const std::string &uri, std::shared_ptr context); - void EmitByKey(const Key &key, const int32_t userId, const std::string &rdbPath, int version); - int GetCount(const Key &key); + void EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version); std::vector GetKeysByUri(const std::string &uri); void Clear(); private: struct ObserverNode { - ObserverNode(const sptr &observer, uint32_t callerTokenId); + ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, + uint32_t callerTokenId = 0); sptr observer; + uint32_t firstCallerTokenId; uint32_t callerTokenId; bool enabled = true; + bool isNotifyOnEnabled = false; }; - class ObserverNodeRecipient : public IRemoteObject::DeathRecipient { - public: - ObserverNodeRecipient(RdbSubscriberManager *owner, const Key &key, sptr observer) - : owner_(owner), key_(key), observer_(observer) {}; - - void OnRemoteDied(const wptr &object) override - { - if (owner_ != nullptr) { - owner_->OnRemoteDied(key_, observer_); - } - } - - private: - RdbSubscriberManager *owner_; - Key key_; - sptr observer_; - }; - - void LinkToDeath(const Key &key, sptr observer); - void OnRemoteDied(const Key &key, sptr observer); RdbSubscriberManager() = default; ConcurrentMap> rdbCache_; - int Notify(const Key &key, const int32_t userId, const std::vector &val, const std::string &rdbDir, + int Notify(const Key &key, int32_t userId, const std::vector &val, const std::string &rdbDir, int rdbVersion); int GetEnableObserverCount(const Key &key); + void SetObserverNotifyOnEnabled(std::vector &nodes); }; } // namespace OHOS::DataShare #endif diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp index 2cd03d0f..1d245bf9 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -26,12 +26,7 @@ namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; std::string GetLocalDeviceId() { - static std::string deviceId; - if (deviceId.empty()) { - deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; - } - - return deviceId; + return DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; } std::vector UserDelegate::GetLocalUserStatus() diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/matrix_event.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/matrix_event.cpp index d3468a8a..d7ce1c13 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/matrix_event.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/matrix_event.cpp @@ -44,5 +44,4 @@ RefCount MatrixEvent::StealRefCount() const { return std::move(refCount_); } - } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp index a0d9f538..5612e8a9 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp @@ -18,6 +18,7 @@ #include "error/general_error.h" #include "log_print.h" +#include "rdb_cloud.h" #include "value_proxy.h" using namespace DistributedDB; @@ -36,29 +37,6 @@ DBStatus RdbAssetLoader::Download(const std::string &tableName, const std::strin if (error == DistributedData::GeneralError::E_OK) { assets = ValueProxy::Convert(std::move(downLoadAssets)); } - return ConvertStatus(static_cast(error)); -} - -DBStatus RdbAssetLoader::ConvertStatus(DistributedData::GeneralError error) -{ - switch (error) { - case DistributedData::GeneralError::E_OK: - return DBStatus::OK; - case DistributedData::GeneralError::E_BUSY: - return DBStatus::BUSY; - case DistributedData::GeneralError::E_INVALID_ARGS: - return DBStatus::INVALID_ARGS; - case DistributedData::GeneralError::E_NOT_SUPPORT: - return DBStatus::NOT_SUPPORT; - case DistributedData::GeneralError::E_ERROR: // fallthrough - case DistributedData::GeneralError::E_NOT_INIT: - case DistributedData::GeneralError::E_ALREADY_CONSUMED: - case DistributedData::GeneralError::E_ALREADY_CLOSED: - return DBStatus::CLOUD_ERROR; - default: - ZLOGE("unknown error:0x%{public}x", error); - break; - } - return DBStatus::CLOUD_ERROR; + return RdbCloud::ConvertStatus(static_cast(error)); } } // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp index aeaad1f9..e41b7664 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -118,19 +118,16 @@ DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) switch (error) { case GeneralError::E_OK: return DBStatus::OK; - case GeneralError::E_BUSY: - return DBStatus::BUSY; - case GeneralError::E_INVALID_ARGS: - return DBStatus::INVALID_ARGS; - case GeneralError::E_NOT_SUPPORT: - return DBStatus::NOT_SUPPORT; - case GeneralError::E_ERROR: // fallthrough - case GeneralError::E_NOT_INIT: - case GeneralError::E_ALREADY_CONSUMED: - case GeneralError::E_ALREADY_CLOSED: - return DBStatus::CLOUD_ERROR; + case GeneralError::E_NETWORK_ERROR: + return DBStatus::CLOUD_NETWORK_ERROR; + case GeneralError::E_LOCKED_BY_OTHERS: + return DBStatus::CLOUD_LOCK_ERROR; + case GeneralError::E_RECODE_LIMIT_EXCEEDED: + return DBStatus::CLOUD_FULL_RECORDS; + case GeneralError::E_NO_SPACE_FOR_ASSET: + return DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT; default: - ZLOGE("unknown error:0x%{public}x", error); + ZLOGI("error:0x%{public}x", error); break; } return DBStatus::CLOUD_ERROR; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h index 0fac9033..161286ea 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.h @@ -38,7 +38,7 @@ public: DBStatus UnLock() override; DBStatus HeartBeat() override; DBStatus Close() override; - DBStatus ConvertStatus(DistributedData::GeneralError error); + static DBStatus ConvertStatus(DistributedData::GeneralError error); private: static constexpr int32_t TO_MS = 1000; // s > ms diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.cpp index 619e7d3a..afa0c827 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.cpp @@ -15,12 +15,13 @@ #include "rdb_cursor.h" -#include "rdb_general_store.h" #include "result_set.h" #include "value_proxy.h" +#include "store_types.h" namespace OHOS::DistributedRdb { using namespace OHOS::DistributedData; -RdbCursor::RdbCursor(std::shared_ptr resultSet) +using namespace DistributedDB; +RdbCursor::RdbCursor(std::shared_ptr resultSet) : resultSet_(std::move(resultSet)) { } @@ -35,36 +36,43 @@ RdbCursor::~RdbCursor() int32_t RdbCursor::GetColumnNames(std::vector &names) const { - return resultSet_->GetAllColumnNames(names); + resultSet_->GetColumnNames(names); + return GeneralError::E_OK; } int32_t RdbCursor::GetColumnName(int32_t col, std::string &name) const { - return resultSet_->GetColumnName(col, name); + return resultSet_->GetColumnName(col, name) == DBStatus::OK ? GeneralError::E_OK : GeneralError::E_ERROR; } int32_t RdbCursor::GetColumnType(int32_t col) const { - NativeRdb::ColumnType columnType; - resultSet_->GetColumnType(col, columnType); - return int32_t(columnType); + ResultSet::ColumnType dbColumnType = ResultSet::ColumnType::INVALID_TYPE; + auto status = resultSet_->GetColumnType(col, dbColumnType); + if (status != DBStatus::OK) { + dbColumnType = ResultSet::ColumnType::INVALID_TYPE; + } + return Convert(dbColumnType); } int32_t RdbCursor::GetCount() const { - int32_t count = -1; - resultSet_->GetRowCount(count); - return count; + return resultSet_->GetCount(); } int32_t RdbCursor::MoveToFirst() { - return resultSet_->GoToFirstRow(); + return resultSet_->MoveToFirst() ? GeneralError::E_OK : GeneralError::E_ERROR; } int32_t RdbCursor::MoveToNext() { - return resultSet_->GoToNextRow(); + return resultSet_->MoveToNext() ? GeneralError::E_OK : GeneralError::E_ERROR; +} + +int32_t RdbCursor::MoveToPrev() +{ + return resultSet_->MoveToPrevious() ? GeneralError::E_OK : GeneralError::E_ERROR; } int32_t RdbCursor::GetEntry(VBucket &entry) @@ -74,37 +82,65 @@ int32_t RdbCursor::GetEntry(VBucket &entry) int32_t RdbCursor::GetRow(VBucket &data) { - NativeRdb::RowEntity bucket; + std::map bucket; auto ret = resultSet_->GetRow(bucket); - data = ValueProxy::Convert(NativeRdb::ValuesBucket(bucket.Steal())); - return ret; + data = ValueProxy::Convert(std::move(bucket)); + return ret == DBStatus::OK ? GeneralError::E_OK : GeneralError::E_ERROR; } -int32_t RdbCursor::Get(int32_t col, Value &value) +int32_t RdbCursor::Get(int32_t col, DistributedData::Value &value) { - NativeRdb::ValueObject object; - auto ret = resultSet_->Get(col, object); - value = ValueProxy::Convert(std::move(object)); - return ret; + std::string name; + auto status = resultSet_->GetColumnName(col, name); + if (status != DBStatus::OK) { + return GeneralError::E_ERROR; + } + VBucket bucket; + if (GetRow(bucket) != GeneralError::E_OK) { + return GeneralError::E_ERROR; + } + value = bucket[name]; + return GeneralError::E_OK; } -int32_t RdbCursor::Get(const std::string &col, Value &value) +int32_t RdbCursor::Get(const std::string &col, DistributedData::Value &value) { int32_t index = -1; auto ret = resultSet_->GetColumnIndex(col, index); - if (ret != NativeRdb::E_OK) { - return ret; + if (ret != DBStatus::OK) { + return GeneralError::E_ERROR; } return Get(index, value); } int32_t RdbCursor::Close() { - return resultSet_->Close(); + resultSet_->Close(); + return GeneralError::E_OK; } bool RdbCursor::IsEnd() { - return false; + return resultSet_->IsAfterLast(); +} + +int32_t RdbCursor::Convert(ResultSet::ColumnType columnType) +{ + switch (columnType) { + case ResultSet::ColumnType::INT64: + return TYPE_INDEX; + case ResultSet::ColumnType::STRING: + return TYPE_INDEX; + case ResultSet::ColumnType::BLOB: + return TYPE_INDEX>; + case ResultSet::ColumnType::DOUBLE: + return TYPE_INDEX; + case ResultSet::ColumnType::NULL_VALUE: + return TYPE_INDEX; + case ResultSet::ColumnType::INVALID_TYPE: + return TYPE_INDEX; + default: + return TYPE_INDEX; + } } } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.h index dd184d49..3aa01820 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cursor.h @@ -16,11 +16,11 @@ #ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H #include "store/cursor.h" -#include "result_set.h" +#include "distributeddb/result_set.h" namespace OHOS::DistributedRdb { class RdbCursor : public DistributedData::Cursor { public: - explicit RdbCursor(std::shared_ptr resultSet); + explicit RdbCursor(std::shared_ptr resultSet); ~RdbCursor(); int32_t GetColumnNames(std::vector &names) const override; int32_t GetColumnName(int32_t col, std::string &name) const override; @@ -28,6 +28,7 @@ public: int32_t GetCount() const override; int32_t MoveToFirst() override; int32_t MoveToNext() override; + int32_t MoveToPrev() override; int32_t GetEntry(DistributedData::VBucket &entry) override; int32_t GetRow(DistributedData::VBucket &data) override; int32_t Get(int32_t col, DistributedData::Value &value) override; @@ -36,7 +37,8 @@ public: bool IsEnd() override; private: - std::shared_ptr resultSet_; + std::shared_ptr resultSet_; + static int32_t Convert(DistributedDB::ResultSet::ColumnType columnType); }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_CURSOR_H 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 88a5e0eb..ce85ed48 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -25,9 +25,11 @@ #include "rdb_cursor.h" #include "rdb_helper.h" #include "rdb_query.h" -#include "rdb_syncer.h" #include "relational_store_manager.h" +#include "utils/anonymous.h" #include "value_proxy.h" +#include "device_manager_adapter.h" +#include "rdb_result_set_impl.h" namespace OHOS::DistributedRdb { using namespace DistributedData; using namespace DistributedDB; @@ -38,17 +40,7 @@ using DBTable = DistributedDB::TableSchema; using DBSchema = DistributedDB::DataBaseSchema; using ClearMode = DistributedDB::ClearMode; using DBStatus = DistributedDB::DBStatus; -class RdbOpenCallbackImpl : public RdbOpenCallback { -public: - int OnCreate(RdbStore &rdbStore) override - { - return NativeRdb::E_OK; - } - int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override - { - return NativeRdb::E_OK; - } -}; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) { @@ -70,23 +62,16 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI } option.observer = &observer_; manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); - RdbStoreConfig config(meta.dataDir); - config.SetCreateNecessary(false); - RdbOpenCallbackImpl callback; - int32_t errCode = NativeRdb::E_OK; - store_ = RdbHelper::GetRdbStore(config, -1, callback, errCode); - if (errCode != NativeRdb::E_OK) { - ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, meta.storeId.c_str()); - } } RdbGeneralStore::~RdbGeneralStore() { manager_.CloseStore(delegate_); delegate_ = nullptr; - store_ = nullptr; bindInfo_.loader_ = nullptr; - bindInfo_.db_->Close(); + if (bindInfo_.db_ != nullptr) { + bindInfo_.db_->Close(); + } bindInfo_.db_ = nullptr; rdbCloud_ = nullptr; rdbLoader_ = nullptr; @@ -104,9 +89,7 @@ int32_t RdbGeneralStore::Bind(const Database &database, BindInfo bindInfo) bindInfo_ = std::move(bindInfo); rdbCloud_ = std::make_shared(bindInfo_.db_); - delegate_->SetCloudDB(rdbCloud_); rdbLoader_ = std::make_shared(bindInfo_.loader_); - delegate_->SetIAssetLoader(rdbLoader_); DBSchema schema; schema.tables.resize(database.tables.size()); for (size_t i = 0; i < database.tables.size(); i++) { @@ -122,6 +105,13 @@ int32_t RdbGeneralStore::Bind(const Database &database, BindInfo bindInfo) dbTable.fields.push_back(std::move(dbField)); } } + std::unique_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database:%{public}s already closed!", Anonymous::Change(database.name).c_str()); + return GeneralError::E_ALREADY_CLOSED; + } + delegate_->SetCloudDB(rdbCloud_); + delegate_->SetIAssetLoader(rdbLoader_); delegate_->SetCloudDbSchema(std::move(schema)); return GeneralError::E_OK; } @@ -133,14 +123,23 @@ bool RdbGeneralStore::IsBound() int32_t RdbGeneralStore::Close() { + 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; } delegate_ = nullptr; - store_ = nullptr; bindInfo_.loader_ = nullptr; - bindInfo_.db_->Close(); + if (bindInfo_.db_ != nullptr) { + bindInfo_.db_->Close(); + } bindInfo_.db_ = nullptr; rdbCloud_ = nullptr; rdbLoader_ = nullptr; @@ -174,7 +173,25 @@ std::shared_ptr RdbGeneralStore::Query(const std::string &table, const s std::shared_ptr RdbGeneralStore::Query(const std::string &table, GenQuery &query) { - return std::shared_ptr(); + RdbQuery *rdbQuery = nullptr; + auto ret = query.QueryInterface(rdbQuery); + if (ret != GeneralError::E_OK || rdbQuery == nullptr) { + ZLOGE("not RdbQuery!"); + return nullptr; + } + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database already closed! tables name:%{public}s", Anonymous::Change(table).c_str()); + return nullptr; + } + if (rdbQuery->IsRemoteQuery()) { + if (rdbQuery->GetDevices().size() != 1) { + ZLOGE("RemoteQuery: devices size error! size:%{public}zu", rdbQuery->GetDevices().size()); + return nullptr; + } + return RemoteQuery(*rdbQuery->GetDevices().begin(), rdbQuery->GetRemoteCondition()); + } + return nullptr; } int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &query, DetailAsync async, int32_t wait) @@ -185,11 +202,18 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &qu if (ret != GeneralError::E_OK || rdbQuery == nullptr) { dbQuery.FromTable(query.GetTables()); } else { - dbQuery = rdbQuery->query_; + dbQuery = rdbQuery->GetQuery(); } auto dbMode = DistributedDB::SyncMode(mode); + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " + "wait:%{public}d", + devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), mode, wait); + return GeneralError::E_ALREADY_CLOSED; + } auto status = (mode < NEARBY_END) - ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), wait) + ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), wait != 0) : (mode > NEARBY_END && mode < CLOUD_END) ? delegate_->Sync(devices, dbMode, dbQuery, GetDBProcessCB(std::move(async)), wait) : DistributedDB::INVALID_ARGS; @@ -198,30 +222,36 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, int32_t mode, GenQuery &qu int32_t RdbGeneralStore::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) { - if (mode < 0 || mode > CloudService::CLEAR_CLOUD_BUTT) { + if (mode < 0 || mode > CLEAN_MODE_BUTT) { return GeneralError::E_INVALID_ARGS; } - int32_t dbMode; DBStatus status; + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d, " + "tableName:%{public}s", + devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), mode, + Anonymous::Change(tableName).c_str()); + return GeneralError::E_ALREADY_CLOSED; + } switch (mode) { - case CloudService::CLEAR_CLOUD_INFO: - dbMode = CleanMode::CLOUD_INFO; - status = delegate_->RemoveDeviceData("", static_cast(dbMode)); + case CLOUD_INFO: + status = delegate_->RemoveDeviceData("", static_cast(CLOUD_INFO)); break; - case CloudService::CLEAR_CLOUD_DATA_AND_INFO: - dbMode = CleanMode::CLOUD_DATA; - status = delegate_->RemoveDeviceData("", static_cast(dbMode)); + case CLOUD_DATA: + status = delegate_->RemoveDeviceData("", static_cast(CLOUD_DATA)); break; - default: + case NEARBY_DATA: if (devices.empty()) { status = delegate_->RemoveDeviceData(); break; } - for (auto device : devices) { status = delegate_->RemoveDeviceData(device, tableName); } break; + default: + return GeneralError::E_ERROR; } return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; } @@ -256,7 +286,7 @@ RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) for (auto &[key, tables] : result) { auto &value = details[key]; value.progress = FINISHED; - value.progress = GeneralError::E_OK; + value.code = GeneralError::E_OK; for (auto &table : tables) { if (table.status != DBStatus::OK) { value.code = GeneralError::E_ERROR; @@ -278,7 +308,7 @@ RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async) for (auto &[id, process] : processes) { auto &detail = details[id]; detail.progress = process.process; - detail.code = process.errCode == DBStatus::OK ? GeneralError::E_OK : GeneralError::E_ERROR; + detail.code = ConvertStatus(process.errCode); for (auto [key, value] : process.tableProcess) { auto &table = detail.details[key]; table.upload.total = value.upLoadInfo.total; @@ -295,20 +325,112 @@ RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async) }; } +int32_t RdbGeneralStore::Release() +{ + auto ref = 1; + { + std::lock_guard lock(mutex_); + if (ref_ == 0) { + return 0; + } + ref = --ref_; + } + ZLOGD("ref:%{public}d", ref); + if (ref == 0) { + delete this; + } + return ref; +} + +int32_t RdbGeneralStore::AddRef() +{ + std::lock_guard lock(mutex_); + if (ref_ == 0) { + return 0; + } + return ++ref_; +} + +int32_t RdbGeneralStore::SetDistributedTables(const std::vector &tables, int32_t type) +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("database already closed! tables size:%{public}zu, type:%{public}d", tables.size(), type); + return GeneralError::E_ALREADY_CLOSED; + } + for (const auto &table : tables) { + ZLOGD("tableName:%{public}s, type:%{public}d", Anonymous::Change(table).c_str(), type); + auto dBStatus = delegate_->CreateDistributedTable(table, static_cast(type)); + if (dBStatus != DistributedDB::DBStatus::OK) { + ZLOGE("create distributed table failed, table:%{public}s, err:%{public}d", + Anonymous::Change(table).c_str(), dBStatus); + return GeneralError::E_ERROR; + } + } + return GeneralError::E_OK; +} + +std::shared_ptr RdbGeneralStore::RemoteQuery(const std::string &device, + const DistributedDB::RemoteCondition &remoteCondition) +{ + std::shared_ptr dbResultSet; + DistributedDB::DBStatus status = + delegate_->RemoteQuery(device, remoteCondition, REMOTE_QUERY_TIME_OUT, dbResultSet); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("DistributedDB remote query failed, device:%{public}s, status is %{public}d.", + Anonymous::Change(device).c_str(), status); + return nullptr; + } + return std::make_shared(dbResultSet); +} + +RdbGeneralStore::GenErr RdbGeneralStore::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; + default: + ZLOGI("status:0x%{public}x", status); + break; + } + return GenErr::E_ERROR; +} + void RdbGeneralStore::ObserverProxy::OnChange(const DBChangedIF &data) { if (!HasWatcher()) { return; } + std::string device = data.GetDataChangeDevice(); + auto networkId = DmAdapter::GetInstance().ToNetworkID(device); + ZLOGD("store:%{public}s data change from :%{public}s", Anonymous::Change(storeId_).c_str(), + Anonymous::Change(device).c_str()); + GenOrigin genOrigin; + genOrigin.origin = GenOrigin::ORIGIN_NEARBY; + genOrigin.dataType = GenOrigin::BASIC_DATA; + DistributedDB::StoreProperty property; + data.GetStoreProperty(property); + genOrigin.id.push_back(networkId); + genOrigin.store = storeId_; + watcher_->OnChange(genOrigin, {}, {}); return; } void RdbGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string &originalId, DBChangedData &&data) { - using GenOrigin = Watcher::Origin; if (!HasWatcher()) { return; } + ZLOGD("store:%{public}s table:%{public}s data change from :%{public}s", Anonymous::Change(storeId_).c_str(), + Anonymous::Change(data.tableName).c_str(), Anonymous::Change(originalId).c_str()); GenOrigin genOrigin; genOrigin.origin = (origin == DBOrigin::ORIGIN_LOCAL) ? GenOrigin::ORIGIN_LOCAL : (origin == DBOrigin::ORIGIN_CLOUD) ? GenOrigin::ORIGIN_CLOUD 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 3213be87..8e1d6b49 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -17,6 +17,8 @@ #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H #include #include +#include + #include "metadata/store_meta_data.h" #include "rdb_asset_loader.h" #include "rdb_cloud.h" @@ -36,6 +38,7 @@ public: using Values = DistributedData::Values; using StoreMetaData = DistributedData::StoreMetaData; using Database = DistributedData::Database; + using GenErr = DistributedData::GeneralError; using RdbStore = OHOS::NativeRdb::RdbStore; explicit RdbGeneralStore(const StoreMetaData &meta); @@ -53,6 +56,9 @@ public: int32_t Watch(int32_t origin, Watcher &watcher) override; int32_t Unwatch(int32_t origin, Watcher &watcher) override; int32_t Close() override; + int32_t AddRef() override; + int32_t Release() override; + int32_t SetDistributedTables(const std::vector &tables, int32_t type) override; private: using RdbDelegate = DistributedDB::RelationalStoreDelegate; @@ -60,12 +66,15 @@ private: using SyncProcess = DistributedDB::SyncProcess; using DBBriefCB = DistributedDB::SyncStatusCallback; using DBProcessCB = std::function &processes)>; - static constexpr uint32_t ITERATE_TIMES = 10000; + static GenErr ConvertStatus(DistributedDB::DBStatus status); + static constexpr inline uint32_t ITERATE_TIMES = 10000; + static constexpr inline uint64_t REMOTE_QUERY_TIME_OUT = 30 * 1000; class ObserverProxy : public DistributedDB::StoreObserver { public: using DBChangedIF = DistributedDB::StoreChangedData; using DBChangedData = DistributedDB::ChangedData; using DBOrigin = DistributedDB::Origin; + using GenOrigin = Watcher::Origin; void OnChange(const DistributedDB::StoreChangedData &data) override; void OnChange(DBOrigin origin, const std::string &originalId, DBChangedData &&data) override; bool HasWatcher() const @@ -79,15 +88,19 @@ private: }; DBBriefCB GetDBBriefCB(DetailAsync async); DBProcessCB GetDBProcessCB(DetailAsync async); + std::shared_ptr RemoteQuery(const std::string &device, + const DistributedDB::RemoteCondition &remoteCondition); ObserverProxy observer_; RdbManager manager_; RdbDelegate *delegate_ = nullptr; - std::shared_ptr store_; std::shared_ptr rdbCloud_ {}; std::shared_ptr rdbLoader_ {}; BindInfo bindInfo_; std::atomic isBound_ = false; + std::mutex mutex_; + int32_t ref_ = 1; + mutable std::shared_mutex rwMutex_; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp index 4830c1fb..733427c9 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.cpp @@ -12,10 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#define LOG_TAG "RdbQuery" #include "rdb_query.h" +#include "log_print.h" +#include "utils/anonymous.h" +#include "value_proxy.h" namespace OHOS::DistributedRdb { using namespace DistributedData; + +RdbQuery::RdbQuery(bool isRemote) : isRemote_(isRemote) {} + bool RdbQuery::IsEqual(uint64_t tid) { return tid == TYPE_ID; @@ -23,6 +29,102 @@ bool RdbQuery::IsEqual(uint64_t tid) std::vector RdbQuery::GetTables() { - return {}; + return tables_; +} + +void RdbQuery::SetDevices(const std::vector &devices) +{ + devices_ = devices; +} + +void RdbQuery::SetSql(const std::string &sql, DistributedData::Values &&args) +{ + sql_ = sql; + args_ = std::move(args); +} + +DistributedDB::Query RdbQuery::GetQuery() const +{ + return query_; +} + +std::vector RdbQuery::GetDevices() const +{ + return devices_; +} + +void RdbQuery::FromTable(const std::vector &tables) +{ + ZLOGD("table count=%{public}zu", tables.size()); + query_.FromTable(tables); +} + +void RdbQuery::MakeQuery(const PredicatesMemo &predicates) +{ + ZLOGD("table=%{public}zu", predicates.tables_.size()); + query_ = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin()) + : DistributedDB::Query::Select(); + if (predicates.tables_.size() > 1) { + query_.FromTable(predicates.tables_); + } + for (const auto &operation : predicates.operations_) { + if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) { + (this->*HANDLES[operation.operator_])(operation); + } + } + devices_ = predicates.devices_; + tables_ = predicates.tables_; +} + +bool RdbQuery::IsRemoteQuery() +{ + return isRemote_; +} + +DistributedDB::RemoteCondition RdbQuery::GetRemoteCondition() const +{ + auto args = args_; + std::vector bindArgs = ValueProxy::Convert(std::move(args)); + return { sql_, bindArgs }; +} + +void RdbQuery::EqualTo(const RdbPredicateOperation &operation) +{ + query_.EqualTo(operation.field_, operation.values_[0]); +} + +void RdbQuery::NotEqualTo(const RdbPredicateOperation &operation) +{ + query_.NotEqualTo(operation.field_, operation.values_[0]); +} + +void RdbQuery::And(const RdbPredicateOperation &operation) +{ + query_.And(); +} + +void RdbQuery::Or(const RdbPredicateOperation &operation) +{ + query_.Or(); +} + +void RdbQuery::OrderBy(const RdbPredicateOperation &operation) +{ + bool isAsc = operation.values_[0] == "true"; + query_.OrderBy(operation.field_, isAsc); +} + +void RdbQuery::Limit(const RdbPredicateOperation &operation) +{ + char *end = nullptr; + int limit = static_cast(strtol(operation.field_.c_str(), &end, DECIMAL_BASE)); + int offset = static_cast(strtol(operation.values_[0].c_str(), &end, DECIMAL_BASE)); + if (limit < 0) { + limit = 0; + } + if (offset < 0) { + offset = 0; + } + query_.Limit(limit, offset); } } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h index aea76acf..41088bd4 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_query.h @@ -17,6 +17,7 @@ #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H #include "rdb_predicates.h" #include "store/general_value.h" +#include "store_types.h" #include "query.h" namespace OHOS::DistributedRdb { class RdbQuery : public DistributedData::GenQuery { @@ -24,14 +25,45 @@ public: using Predicates = NativeRdb::RdbPredicates; static constexpr uint64_t TYPE_ID = 0x20000001; RdbQuery() = default; + explicit RdbQuery(bool isRemote); ~RdbQuery() override = default; bool IsEqual(uint64_t tid) override; std::vector GetTables() override; + std::vector GetDevices() const; + DistributedDB::Query GetQuery() const; + DistributedDB::RemoteCondition GetRemoteCondition() const; + bool IsRemoteQuery(); + void SetDevices(const std::vector &devices); + void SetSql(const std::string &sql, DistributedData::Values &&args); + void FromTable(const std::vector &tables); + void MakeQuery(const PredicatesMemo &predicates); + +private: + void EqualTo(const RdbPredicateOperation& operation); + void NotEqualTo(const RdbPredicateOperation& operation); + void And(const RdbPredicateOperation& operation); + void Or(const RdbPredicateOperation& operation); + void OrderBy(const RdbPredicateOperation& operation); + void Limit(const RdbPredicateOperation& operation); + using PredicateHandle = void (RdbQuery::*)(const RdbPredicateOperation &operation); + static constexpr inline PredicateHandle HANDLES[OPERATOR_MAX] = { + &RdbQuery::EqualTo, + &RdbQuery::NotEqualTo, + &RdbQuery::And, + &RdbQuery::Or, + &RdbQuery::OrderBy, + &RdbQuery::Limit, + }; + static constexpr inline uint32_t DECIMAL_BASE = 10; DistributedDB::Query query_; + bool isRemote_ = false; std::string sql_; + DistributedData::Values args_; + std::vector devices_; + std::vector tables_; }; } // namespace OHOS::DistributedRdb #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_QUERY_H diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp index 1be8c197..348fb808 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.cpp @@ -15,232 +15,227 @@ #define LOG_TAG "RdbResultSetImpl" +#include "rdb_result_set_impl.h" #include "log_print.h" -#include "rdb_errno.h" #include "store_types.h" -#include "rdb_result_set_impl.h" +#include "store/cursor.h" using DistributedDB::DBStatus; using OHOS::NativeRdb::ColumnType; namespace OHOS::DistributedRdb { -RdbResultSetImpl::RdbResultSetImpl(std::shared_ptr resultSet) +using OHOS::DistributedData::GeneralError; +using Cursor = OHOS::DistributedData::Cursor; +RdbResultSetImpl::RdbResultSetImpl(std::shared_ptr resultSet) : resultSet_(std::move(resultSet)) { - resultSet_ = std::move(resultSet); + if (resultSet_ != nullptr) { + count_ = resultSet_->GetCount(); + resultSet_->GetColumnNames(colNames_); + } } int RdbResultSetImpl::GetAllColumnNames(std::vector &columnNames) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - resultSet_->GetColumnNames(columnNames); + columnNames = colNames_; return NativeRdb::E_OK; } int RdbResultSetImpl::GetColumnCount(int &count) { - return NativeRdb::E_NOT_SUPPORT; + std::shared_lock lock(mutex_); + if (resultSet_ == nullptr) { + return NativeRdb::E_STEP_RESULT_CLOSED; + } + count = static_cast(colNames_.size()); + return NativeRdb::E_OK; } int RdbResultSetImpl::GetColumnType(int columnIndex, ColumnType &columnType) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DbColumnType dbColumnType; - DBStatus status = resultSet_->GetColumnType(columnIndex, dbColumnType); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; - } - columnType = ConvertColumnType(dbColumnType); + columnType = ConvertColumnType(resultSet_->GetColumnType(columnIndex)); return NativeRdb::E_OK; } int RdbResultSetImpl::GetColumnIndex(const std::string &columnName, int &columnIndex) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->GetColumnIndex(columnName, columnIndex); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; + for (size_t i = 0; i < colNames_.size(); i++) { + if (colNames_[i] == columnName) { + columnIndex = i; + return NativeRdb::E_OK; + } } - return NativeRdb::E_OK; + return NativeRdb::E_ERROR; } int RdbResultSetImpl::GetColumnName(int columnIndex, std::string &columnName) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->GetColumnName(columnIndex, columnName); - if (status != DBStatus::OK) { + if (colNames_.size() <= static_cast(columnIndex) || columnIndex < 0) { return NativeRdb::E_ERROR; } + columnName = colNames_[columnIndex]; return NativeRdb::E_OK; } int RdbResultSetImpl::GetRowCount(int &count) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - count = resultSet_->GetCount(); + count = count_; return NativeRdb::E_OK; } int RdbResultSetImpl::GetRowIndex(int &position) const { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - position = resultSet_->GetPosition(); + position = current_; return NativeRdb::E_OK; } int RdbResultSetImpl::GoTo(int offset) { - std::shared_lock lock(this->mutex_); - if (resultSet_ == nullptr) { - return NativeRdb::E_STEP_RESULT_CLOSED; - } - if (!resultSet_->Move(offset)) { - return NativeRdb::E_ERROR; + int ret = NativeRdb::E_OK; + while (offset != 0 && ret == NativeRdb::E_OK) { + if (offset > 0) { + ret = GoToNextRow(); + offset--; + } else { + ret = GoToPreviousRow(); + offset++; + } } - return NativeRdb::E_OK; + return ret; } int RdbResultSetImpl::GoToRow(int position) { - std::shared_lock lock(this->mutex_); - if (resultSet_ == nullptr) { - return NativeRdb::E_STEP_RESULT_CLOSED; - } - if (!resultSet_->MoveToPosition(position)) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return GoTo(position - current_); } int RdbResultSetImpl::GoToFirstRow() { - std::shared_lock lock(this->mutex_); + std::unique_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - if (!resultSet_->MoveToFirst()) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + auto ret = resultSet_->MoveToFirst(); + current_ = 0; + return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR; } int RdbResultSetImpl::GoToLastRow() { - std::shared_lock lock(this->mutex_); - if (resultSet_ == nullptr) { - return NativeRdb::E_STEP_RESULT_CLOSED; - } - if (!resultSet_->MoveToLast()) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return GoToRow(count_ - 1); } int RdbResultSetImpl::GoToNextRow() { - std::shared_lock lock(this->mutex_); + std::unique_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - if (!resultSet_->MoveToNext()) { + if (current_ >= count_ - 1) { + current_ = count_; return NativeRdb::E_ERROR; } - return NativeRdb::E_OK; + + auto ret = resultSet_->MoveToNext(); + current_++; + return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR; } int RdbResultSetImpl::GoToPreviousRow() { - std::shared_lock lock(this->mutex_); + std::unique_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - if (!resultSet_->MoveToPrevious()) { + if (current_ <= 0) { + current_ = -1; return NativeRdb::E_ERROR; } - return NativeRdb::E_OK; + + auto ret = resultSet_->MoveToPrev(); + current_--; + return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR; } int RdbResultSetImpl::IsEnded(bool &result) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - result = resultSet_->IsAfterLast(); + result = current_ >= count_ || count_ <= 0; return NativeRdb::E_OK; } int RdbResultSetImpl::IsStarted(bool &result) const { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - result = resultSet_->IsBeforeFirst(); + result = current_ < 0 || count_ <= 0; return NativeRdb::E_OK; } int RdbResultSetImpl::IsAtFirstRow(bool &result) const { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - result = resultSet_->IsFirst(); + result = count_ > 0 && current_ == 0; return NativeRdb::E_OK; } int RdbResultSetImpl::IsAtLastRow(bool &result) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - result = resultSet_->IsLast(); + result = count_ > 0 && current_ == count_ - 1; return NativeRdb::E_OK; } -int RdbResultSetImpl::GetBlob(int columnIndex, std::vector &blob) +int RdbResultSetImpl::GetBlob(int columnIndex, std::vector &value) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->Get(columnIndex, blob); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return Get(columnIndex, value); } int RdbResultSetImpl::GetString(int columnIndex, std::string &value) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->Get(columnIndex, value); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return Get(columnIndex, value); } int RdbResultSetImpl::GetInt(int columnIndex, int &value) @@ -259,56 +254,46 @@ int RdbResultSetImpl::GetInt(int columnIndex, int &value) int RdbResultSetImpl::GetLong(int columnIndex, int64_t &value) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->Get(columnIndex, value); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return Get(columnIndex, value); } int RdbResultSetImpl::GetDouble(int columnIndex, double &value) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->Get(columnIndex, value); - if (status != DBStatus::OK) { - return NativeRdb::E_ERROR; - } - return NativeRdb::E_OK; + return Get(columnIndex, value); } int RdbResultSetImpl::IsColumnNull(int columnIndex, bool &isNull) { - std::shared_lock lock(this->mutex_); + std::shared_lock lock(mutex_); if (resultSet_ == nullptr) { return NativeRdb::E_STEP_RESULT_CLOSED; } - DBStatus status = resultSet_->IsColumnNull(columnIndex, isNull); - if (status != DBStatus::OK) { + DistributedData::Value var; + auto status = resultSet_->Get(columnIndex, var); + if (status != DistributedData::GeneralError::E_OK) { return NativeRdb::E_ERROR; } + isNull = var.index() == DistributedData::TYPE_INDEX; return NativeRdb::E_OK; } bool RdbResultSetImpl::IsClosed() const { - std::shared_lock lock(this->mutex_); - if (resultSet_ == nullptr) { - ZLOGW("resultSet already closed."); - return true; - } - return resultSet_->IsClosed(); + std::shared_lock lock(mutex_); + return resultSet_ == nullptr; } int RdbResultSetImpl::Close() { - std::unique_lock lock(this->mutex_); + std::unique_lock lock(mutex_); if (resultSet_ == nullptr) { ZLOGW("Result set has been closed."); return NativeRdb::E_OK; @@ -318,21 +303,11 @@ int RdbResultSetImpl::Close() return NativeRdb::E_OK; } -ColumnType RdbResultSetImpl::ConvertColumnType(DbColumnType columnType) const +ColumnType RdbResultSetImpl::ConvertColumnType(int32_t columnType) const { - switch (columnType) { - case DbColumnType::INT64: - return ColumnType::TYPE_INTEGER; - case DbColumnType::STRING: - return ColumnType::TYPE_STRING; - case DbColumnType::BLOB: - return ColumnType::TYPE_BLOB; - case DbColumnType::DOUBLE: - return ColumnType::TYPE_FLOAT; - case DbColumnType::NULL_VALUE: - return ColumnType::TYPE_NULL; - default: - return ColumnType::TYPE_NULL; + if (static_cast(columnType) >= DistributedData::TYPE_MAX || columnType < 0) { + return ColumnType::TYPE_NULL; } + return COLUMNTYPES[columnType]; } } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h index 63e16f45..58650063 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_result_set_impl.h @@ -18,13 +18,15 @@ #include #include "rdb_result_set_stub.h" -#include "distributeddb/result_set.h" +#include "rdb_errno.h" +#include "store/cursor.h" +#include "value_proxy.h" +#include "store/general_value.h" namespace OHOS::DistributedRdb { class RdbResultSetImpl final : public RdbResultSetStub { public: - using DbColumnType = DistributedDB::ResultSet::ColumnType; - explicit RdbResultSetImpl(std::shared_ptr resultSet); + explicit RdbResultSetImpl(std::shared_ptr resultSet); ~RdbResultSetImpl() override {}; int GetAllColumnNames(std::vector &columnNames) override; int GetColumnCount(int &count) override; @@ -43,7 +45,7 @@ public: int IsStarted(bool &result) const override; int IsAtFirstRow(bool &result) const override; int IsAtLastRow(bool &result) override; - int GetBlob(int columnIndex, std::vector &blob) override; + int GetBlob(int columnIndex, std::vector &value) override; int GetString(int columnIndex, std::string &value) override; int GetInt(int columnIndex, int &value) override; int GetLong(int columnIndex, int64_t &value) override; @@ -53,9 +55,41 @@ public: int Close() override; private: + template + std::enable_if_t < ValueProxy::CVT_INDEX + Get(int columnIndex, T &value) const + { + auto [ret, val] = GetValue(columnIndex); + value = val.operator T(); + return ret; + }; + + std::pair GetValue(int columnIndex) const + { + DistributedData::Value var; + auto status = resultSet_->Get(columnIndex, var); + if (status != DistributedData::GeneralError::E_OK) { + return { NativeRdb::E_ERROR, ValueProxy::Value() }; + } + return {NativeRdb::E_OK, ValueProxy::Convert(std::move(var))}; + }; + mutable std::shared_mutex mutex_ {}; - std::shared_ptr resultSet_; - ColumnType ConvertColumnType(DbColumnType columnType) const; + static constexpr ColumnType COLUMNTYPES[DistributedData::TYPE_MAX] = { + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_NULL, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_INTEGER, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_FLOAT, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_STRING, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_INTEGER, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_BLOB, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_BLOB, + [DistributedData::TYPE_INDEX] = ColumnType::TYPE_BLOB, + }; + std::shared_ptr resultSet_; + std::atomic current_ = -1; + int32_t count_ = 0; + std::vector colNames_; + ColumnType ConvertColumnType(int32_t columnType) const; }; } // namespace OHOS::DistributedRdb #endif // DISTRIBUTED_RDB_RDB_RESULT_SET_IMPL_H 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 491d38e3..9994fee7 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -18,6 +18,7 @@ #include "account/account_delegate.h" #include "checker/checker_manager.h" #include "cloud/cloud_event.h" +#include "cloud/change_event.h" #include "communicator/device_manager_adapter.h" #include "crypto_manager.h" #include "directory/directory_manager.h" @@ -30,12 +31,14 @@ #include "rdb_watcher.h" #include "rdb_notifier_proxy.h" #include "rdb_query.h" +#include "store/general_store.h" #include "types_export.h" #include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" #include "cloud/schema_meta.h" #include "rdb_general_store.h" +#include "rdb_result_set_impl.h" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; @@ -67,7 +70,7 @@ RdbServiceImpl::Factory::~Factory() { } -RdbServiceImpl::RdbServiceImpl() : autoLaunchObserver_(this) +RdbServiceImpl::RdbServiceImpl() { ZLOGI("construct"); DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback( @@ -126,16 +129,16 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib param.appId = entry.appId; param.storeId = entry.storeId; param.path = entry.dataDir; - param.option.storeObserver = &autoLaunchObserver_; + param.option.storeObserver = nullptr; param.option.isEncryptedDb = entry.isEncrypt; if (entry.isEncrypt) { param.option.iterateTimes = ITERATE_TIMES; param.option.cipher = DistributedDB::CipherType::AES_256_GCM; - RdbSyncer::GetPassword(entry, param.option.passwd); + GetPassword(entry, param.option.passwd); } + AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId)); return true; } - ZLOGE("not find identifier"); return false; } @@ -143,23 +146,12 @@ 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) { OnClientDied(pid); - AutoCache::GetInstance().CloseStore(tokenId); return E_OK; } void RdbServiceImpl::OnClientDied(pid_t pid) { ZLOGI("client dead pid=%{public}d", pid); - syncers_.ComputeIfPresent(pid, [this](const auto& key, StoreSyncersType& syncers) { - syncerNum_ -= static_cast(syncers.size()); - for (const auto& [name, syncer] : syncers) { - executors_->Remove(syncer->GetTimerId()); - } - return false; - }); - identifiers_.EraseIf([pid](const auto &key, std::pair &value) { - return value.first == pid; - }); syncAgents_.EraseIf([pid](auto &key, SyncAgent &agent) { return agent.pid_ == pid; }); } @@ -169,8 +161,8 @@ bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::strin storeInfo.uid = IPCSkeleton::GetCallingUid(); storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); storeInfo.bundleName = bundleName; - storeInfo.storeId = RdbSyncer::RemoveSuffix(storeName); - auto [instanceId, user] = RdbSyncer::GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName); + storeInfo.storeId = RemoveSuffix(storeName); + auto [instanceId, user] = GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName); if (instanceId != 0) { return false; } @@ -214,163 +206,45 @@ int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptrOnChange(origin, {}, {}); - } -} - -void RdbServiceImpl::SyncerTimeout(std::shared_ptr syncer) +std::shared_ptr RdbServiceImpl::GetStore(const RdbSyncerParam ¶m) { - if (syncer == nullptr) { - return; - } - auto storeId = syncer->GetStoreId(); - ZLOGI("%{public}s", Anonymous::Change(storeId).c_str()); - syncers_.ComputeIfPresent(syncer->GetPid(), [this, storeId](const auto& key, StoreSyncersType& syncers) { - syncers.erase(storeId); - syncerNum_--; - return true; - }); -} - -std::shared_ptr RdbServiceImpl::GetRdbSyncer(const RdbSyncerParam ¶m) -{ - pid_t pid = IPCSkeleton::GetCallingPid(); - pid_t uid = IPCSkeleton::GetCallingUid(); - uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); - std::shared_ptr syncer; - syncers_.Compute(pid, [this, ¶m, pid, uid, tokenId, &syncer] (const auto& key, StoreSyncersType& syncers) { - auto storeId = RdbSyncer::RemoveSuffix(param.storeName_); - auto it = syncers.find(storeId); - if (it != syncers.end()) { - syncer = it->second; - if (!param.isEncrypt_ || param.password_.empty()) { - executors_->Remove(syncer->GetTimerId(), true); - auto timerId = executors_->Schedule(std::chrono::milliseconds(SYNCER_TIMEOUT), [this, syncer] { - SyncerTimeout(syncer); - }); - syncer->SetTimerId(timerId); - return true; - } - syncers.erase(storeId); - } - if (syncers.size() >= MAX_SYNCER_PER_PROCESS || syncerNum_ >= MAX_SYNCER_NUM) { - ZLOGE("pid: %{public}d, syncers size: %{public}zu. syncerNum: %{public}d", pid, syncers.size(), syncerNum_); - return !syncers.empty(); - } - auto rdbObserver = new (std::nothrow) RdbStoreObserverImpl(this, pid, tokenId); - if (rdbObserver == nullptr) { - return !syncers.empty(); - } - auto syncer_ = std::make_shared(param, rdbObserver); - StoreMetaData storeMetaData = GetStoreMetaData(param); - MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData); - if (syncer_->Init(pid, uid, tokenId, storeMetaData) != RDB_OK) { - return !syncers.empty(); - } - syncers[storeId] = syncer_; - syncer = syncer_; - syncerNum_++; - auto timerId = executors_->Schedule(std::chrono::milliseconds(SYNCER_TIMEOUT), [this, syncer] { - SyncerTimeout(syncer); - }); - syncer->SetTimerId(timerId); - return !syncers.empty(); - }); - - if (syncer != nullptr) { - identifiers_.Insert(syncer->GetIdentifier(), { pid, tokenId }); - } else { - ZLOGE("syncer is nullptr"); + StoreMetaData storeMetaData = GetStoreMetaData(param); + MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData); + auto watchers = GetWatchers(storeMetaData.tokenId, storeMetaData.storeId); + auto store = AutoCache::GetInstance().GetStore(storeMetaData, watchers); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str()); } - return syncer; + return store; } int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, int32_t type) { - ZLOGI("enter"); if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); + ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } - auto syncer = GetRdbSyncer(param); - if (syncer == nullptr) { + auto store = GetStore(param); + if (store == nullptr) { + ZLOGE("bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } - return syncer->SetDistributedTables(tables, type); -} -std::pair RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const Option &option, - const PredicatesMemo &pred) -{ - if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); - return {RDB_ERROR, {}}; - } - auto syncer = GetRdbSyncer(param); - if (syncer == nullptr) { - return {RDB_ERROR, {}}; - } - Details details = {}; - auto status = syncer->DoSync(option, pred, [&details, ¶m](auto &&result) mutable { - ZLOGD("Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), - Anonymous::Change(param.storeName_).c_str()); - details = std::move(result); - }); - return { status, std::move(details) }; + return store->SetDistributedTables(tables, type); } void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result) { - ZLOGI("pid=%{public}x seqnum=%{public}u", tokenId, seqNum); + 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)); } } -int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred) -{ - if (!CheckAccess(param.bundleName_, param.storeName_)) { - ZLOGE("permission error"); - return RDB_ERROR; - } - auto tokenId = IPCSkeleton::GetCallingTokenID(); - ZLOGI("seq num=%{public}u", option.seqNum); - auto syncer = GetRdbSyncer(param); - if (syncer == nullptr) { - return RDB_ERROR; - } - return syncer->DoSync(option, pred, [this, tokenId, seqNum = option.seqNum](Details &&result) { - OnAsyncComplete(tokenId, seqNum, std::move(result)); - }); -} - std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr) { if (origStr.empty()) { @@ -386,19 +260,6 @@ std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr) return tmp; } -std::string RdbServiceImpl::GenIdentifier(const RdbSyncerParam ¶m) -{ - pid_t uid = IPCSkeleton::GetCallingUid(); - uint32_t token = IPCSkeleton::GetCallingTokenID(); - auto storeId = RdbSyncer::RemoveSuffix(param.storeName_); - CheckerManager::StoreInfo storeInfo { uid, token, param.bundleName_, storeId }; - auto userId = AccountDelegate::GetInstance()->GetUserByToken(token); - std::string appId = CheckerManager::GetInstance().GetAppId(storeInfo); - std::string identifier = RelationalStoreManager::GetRelationalStoreIdentifier( - std::to_string(userId), appId, storeId); - return TransferStringToHex(identifier); -} - AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName) { auto [success, agent] = syncAgents_.Find(tokenId); @@ -408,92 +269,138 @@ AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::str return { agent.watcher_ }; } -void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName) +int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, + const std::vector& selectionArgs, sptr& resultSet) { - pid_ = pid; - count_ = 0; - bundleName_ = bundleName; - notifier_ = nullptr; - if (watcher_ != nullptr) { - watcher_->SetNotifier(nullptr); + if (!CheckAccess(param.bundleName_, param.storeName_)) { + ZLOGE("permission error"); + return RDB_ERROR; } -} - -void RdbServiceImpl::SyncAgent::SetNotifier(sptr notifier) -{ - notifier_ = notifier; - if (watcher_ != nullptr) { - watcher_->SetNotifier(notifier); + auto store = GetStore(param); + if (store == nullptr) { + ZLOGE("store is null"); + return RDB_ERROR; } -} - -void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr watcher) -{ - if (watcher_ != watcher) { - watcher_ = watcher; - if (watcher_ != nullptr) { - watcher_->SetNotifier(notifier_); - } + auto values = ValueProxy::Convert(selectionArgs); + RdbQuery rdbQuery(true); + rdbQuery.SetDevices({ device }); + rdbQuery.SetSql(sql, std::move(values)); + auto cursor = store->Query("", rdbQuery); + if (cursor == nullptr) { + ZLOGE("Query failed, cursor is null"); + return RDB_ERROR; + } + resultSet = new (std::nothrow) RdbResultSetImpl(cursor); + if (resultSet == nullptr) { + ZLOGE("new resultSet failed"); + return RDB_ERROR; } + return RDB_OK; } -int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) +int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, + const AsyncDetail &async) { if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); return RDB_ERROR; } - auto syncer = GetRdbSyncer(param); - if (syncer == nullptr) { - ZLOGE("syncer is null"); - return RDB_ERROR; + if (option.mode < DistributedData::GeneralStore::CLOUD_END && + option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) { + DoCloudSync(param, option, predicates, async); + return RDB_OK; } - return syncer->RemoteQuery(device, sql, selectionArgs, resultSet); + return DoSync(param, option, predicates, async); } -int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, - const AsyncDetail &async) +int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option &option, + const PredicatesMemo &predicates, const AsyncDetail &async) { + auto store = GetStore(param); + if (store == nullptr) { + return RDB_ERROR; + } + RdbQuery rdbQuery; + rdbQuery.MakeQuery(predicates); if (!option.isAsync) { - auto [status, details] = DoSync(param, option, predicates); + Details details = {}; + auto status = store->Sync( + DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, 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); + }, + true); if (async != nullptr) { async(std::move(details)); } return status; } - return DoAsync(param, option, predicates); + ZLOGD("seqNum=%{public}u", option.seqNum); + auto tokenId = IPCSkeleton::GetCallingTokenID(); + return store->Sync( + DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, rdbQuery, + [this, tokenId, seqNum = option.seqNum](const GenDetails &result) mutable { + OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result)); + }, + false); +} + +void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService::Option &option, + const PredicatesMemo &predicates, const AsyncDetail &async) +{ + CloudEvent::StoreInfo storeInfo; + storeInfo.bundleName = param.bundleName_; + storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); + storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId); + storeInfo.storeName = param.storeName_; + std::shared_ptr query = nullptr; + if (!predicates.tables_.empty()) { + query = std::make_shared(); + query->FromTable(predicates.tables_); + } + GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum]( + const GenDetails &result) mutable { + OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result)); + }; + GenAsync syncCallback = [async, ¶m](const GenDetails &details) { + ZLOGD("Cloud Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); + if (async != nullptr) { + async(HandleGenDetails(details)); + } + }; + + auto info = ChangeEvent::EventInfo(option.mode, (option.isAsync ? 0 : WAIT_TIME), + (option.isAsync && option.seqNum == 0), query, (option.isAsync ? asyncCallback : syncCallback)); + auto evt = std::make_unique(std::move(storeInfo), std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); } int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) { + if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) { + ZLOGE("mode:%{public}d error", option.mode); + return RDB_ERROR; + } pid_t pid = IPCSkeleton::GetCallingPid(); auto tokenId = IPCSkeleton::GetCallingTokenID(); - switch (option.mode) { - case SubscribeMode::REMOTE: { - auto identifier = GenIdentifier(param); - identifiers_.Insert(identifier, std::pair { pid, tokenId }); - ZLOGI("%{public}s %{public}.6s %{public}d", Anonymous::Change(param.storeName_).c_str(), - identifier.c_str(), pid); - break; + bool isCreate = false; + syncAgents_.Compute(tokenId, [pid, ¶m, &isCreate](auto &key, SyncAgent &agent) { + if (pid != agent.pid_) { + agent.ReInit(pid, param.bundleName_); } - case SubscribeMode::CLOUD: // fallthrough - case SubscribeMode::CLOUD_DETAIL: { - syncAgents_.Compute(tokenId, [pid, ¶m](auto &key, SyncAgent &agent) { - if (pid != agent.pid_) { - agent.ReInit(pid, param.bundleName_); - } - if (agent.watcher_ == nullptr) { - agent.SetWatcher(std::make_shared()); - } - agent.count_++; - return true; - }); - break; + if (agent.watcher_ == nullptr) { + isCreate = true; + agent.SetWatcher(std::make_shared()); } - default: - return RDB_ERROR; + agent.count_++; + return true; + }); + if (isCreate) { + AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_)); } return RDB_OK; } @@ -501,29 +408,24 @@ int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOp int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) { - switch (option.mode) { - case SubscribeMode::REMOTE: { - auto identifier = GenIdentifier(param); - ZLOGI("%{public}s %{public}.6s", param.storeName_.c_str(), identifier.c_str()); - identifiers_.Erase(identifier); - break; + if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) { + ZLOGE("mode:%{public}d error", option.mode); + return RDB_ERROR; + } + bool destroyed = false; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + syncAgents_.ComputeIfPresent(tokenId, [&destroyed](auto &key, SyncAgent &agent) { + if (agent.count_ > 0) { + agent.count_--; } - case SubscribeMode::CLOUD: // fallthrough - case SubscribeMode::CLOUD_DETAIL: { - syncAgents_.ComputeIfPresent(IPCSkeleton::GetCallingTokenID(), [](auto &key, SyncAgent &agent) { - if (agent.count_ > 0) { - agent.count_--; - } - if (agent.count_ == 0) { - agent.SetWatcher(nullptr); - } - return true; - }); - break; + if (agent.count_ == 0) { + destroyed = true; + agent.SetWatcher(nullptr); } - default: - ZLOGI("mode:%{public}d", option.mode); - return RDB_ERROR; + return true; + }); + if (destroyed) { + AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_)); } return RDB_OK; } @@ -548,8 +450,8 @@ int32_t RdbServiceImpl::GetSchema(const RdbSyncerParam ¶m) CloudEvent::StoreInfo storeInfo; storeInfo.tokenId = IPCSkeleton::GetCallingTokenID(); storeInfo.bundleName = param.bundleName_; - storeInfo.storeName = RdbSyncer::RemoveSuffix(param.storeName_); - auto [instanceId, user]= RdbSyncer::GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_); + storeInfo.storeName = RemoveSuffix(param.storeName_); + auto [instanceId, user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_); storeInfo.instanceId = instanceId; storeInfo.user = user; executors_->Execute([storeInfo]() { @@ -566,11 +468,11 @@ StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m) StoreMetaData metaData; metaData.uid = IPCSkeleton::GetCallingUid(); metaData.tokenId = IPCSkeleton::GetCallingTokenID(); - auto [instanceId, user] = RdbSyncer::GetInstIndexAndUser(metaData.tokenId, param.bundleName_); + auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_); metaData.instanceId = instanceId; metaData.bundleName = param.bundleName_; metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - metaData.storeId = RdbSyncer::RemoveSuffix(param.storeName_); + metaData.storeId = RemoveSuffix(param.storeName_); metaData.user = std::to_string(user); metaData.storeType = param.type_; metaData.securityLevel = param.level_; @@ -637,20 +539,111 @@ int32_t RdbServiceImpl::SetSecretKey(const RdbSyncerParam ¶m, const StoreMet int32_t RdbServiceImpl::Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old) { if (old.storeType == RDB_DEVICE_COLLABORATION && old.version < StoreMetaData::UUID_CHANGED_TAG) { - auto syncer = GetRdbSyncer(param); - if (syncer == nullptr) { - ZLOGE("syncer is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + auto store = GetStore(param); + if (store == nullptr) { + ZLOGE("store is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str()); return RDB_ERROR; } - return syncer->RemoveDeviceData(); + return store->Clean({}, GeneralStore::CleanMode::NEARBY_DATA, "") == GeneralError::E_OK ? RDB_OK : RDB_ERROR; } return RDB_OK; } +Details RdbServiceImpl::HandleGenDetails(const GenDetails &details) +{ + Details dbDetails; + for (const auto& [id, detail] : details) { + auto &dbDetail = dbDetails[id]; + dbDetail.progress = detail.progress; + dbDetail.code = detail.code; + for (auto &[name, table] : detail.details) { + auto &dbTable = dbDetail.details[name]; + Constant::Copy(&dbTable, &table); + } + } + return dbDetails; +} + +bool RdbServiceImpl::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) +{ + if (!metaData.isEncrypt) { + return true; + } + + std::string key = metaData.GetSecretKey(); + DistributedData::SecretKeyMetaData secretKeyMeta; + MetaDataManager::GetInstance().LoadMeta(key, secretKeyMeta, true); + std::vector decryptKey; + CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); + if (password.SetValue(decryptKey.data(), decryptKey.size()) != DistributedDB::CipherPassword::OK) { + std::fill(decryptKey.begin(), decryptKey.end(), 0); + ZLOGE("Set secret key value failed. len is (%{public}d)", int32_t(decryptKey.size())); + return false; + } + std::fill(decryptKey.begin(), decryptKey.end(), 0); + return true; +} + +std::string RdbServiceImpl::RemoveSuffix(const std::string& name) +{ + std::string suffix(".db"); + auto pos = name.rfind(suffix); + if (pos == std::string::npos || pos < name.length() - suffix.length()) { + return name; + } + return std::string(name, 0, pos); +} + +std::pair RdbServiceImpl::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName) +{ + if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { + return { 0, 0 }; + } + + HapTokenInfo tokenInfo; + tokenInfo.instIndex = -1; + int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (errCode != RET_SUCCESS) { + ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId, + bundleName.c_str()); + return { -1, -1 }; + } + return { tokenInfo.instIndex, tokenInfo.userID }; +} + int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo) { executors_ = bindInfo.executors; return 0; } + +void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName) +{ + pid_ = pid; + count_ = 0; + bundleName_ = bundleName; + notifier_ = nullptr; + if (watcher_ != nullptr) { + watcher_->SetNotifier(nullptr); + } +} + +void RdbServiceImpl::SyncAgent::SetNotifier(sptr notifier) +{ + notifier_ = notifier; + if (watcher_ != nullptr) { + watcher_->SetNotifier(notifier); + } +} + +void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr watcher) +{ + if (watcher_ != watcher) { + watcher_ = watcher; + if (watcher_ != nullptr) { + watcher_->SetNotifier(notifier_); + } + } +} } // namespace OHOS::DistributedRdb 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 061e5489..f09d641b 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -25,11 +25,12 @@ #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data.h" #include "rdb_notifier_proxy.h" -#include "rdb_syncer.h" #include "rdb_watcher.h" #include "store/auto_cache.h" +#include "store/general_store.h" #include "store_observer.h" #include "visibility.h" +#include "store/general_value.h" namespace OHOS::DistributedRdb { class API_EXPORT RdbServiceImpl : public RdbServiceStub { public: @@ -58,8 +59,6 @@ public: int32_t UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) override; - void OnDataChange(pid_t pid, uint32_t tokenId, const DistributedDB::StoreChangedData& data); - int32_t ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) override; int32_t OnInitialize() override; @@ -90,25 +89,20 @@ private: private: std::shared_ptr product_; }; - using StoreSyncersType = std::map>; - - static constexpr int32_t MAX_SYNCER_NUM = 50; - static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; - static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms - std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); + static constexpr inline uint32_t WAIT_TIME = 30 * 1000; - int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); + void DoCloudSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, + const AsyncDetail &async); + + int DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, + const AsyncDetail &async); Watchers GetWatchers(uint32_t tokenId, const std::string &storeName); - std::string GenIdentifier(const RdbSyncerParam& param); - bool CheckAccess(const std::string& bundleName, const std::string& storeName); - void SyncerTimeout(std::shared_ptr syncer); - - std::shared_ptr GetRdbSyncer(const RdbSyncerParam& param); + std::shared_ptr GetStore(const RdbSyncerParam& param); void OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details&& result); @@ -120,14 +114,18 @@ private: int32_t Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old); + static Details HandleGenDetails(const DistributedData::GenDetails &details); + static std::string TransferStringToHex(const std::string& origStr); + static std::string RemoveSuffix(const std::string& name); + + static std::pair GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName); + + static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); + static Factory factory_; - int32_t syncerNum_ {}; - ConcurrentMap syncers_; - ConcurrentMap> identifiers_; ConcurrentMap syncAgents_; - RdbStoreObserverImpl autoLaunchObserver_; std::shared_ptr executors_; }; } // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp deleted file mode 100644 index 9fbd7642..00000000 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "RdbSyncer" -#include "rdb_syncer.h" - -#include - -#include "accesstoken_kit.h" -#include "account/account_delegate.h" -#include "checker/checker_manager.h" -#include "cloud/change_event.h" -#include "crypto_manager.h" -#include "device_manager_adapter.h" -#include "eventcenter/event_center.h" -#include "log_print.h" -#include "metadata/meta_data_manager.h" -#include "rdb_query.h" -#include "rdb_result_set_impl.h" -#include "store/general_store.h" -#include "types_export.h" -#include "utils/anonymous.h" -#include "utils/constant.h" -#include "utils/converter.h" -using OHOS::DistributedKv::AccountDelegate; -using namespace OHOS::Security::AccessToken; -using namespace OHOS::DistributedData; -using system_clock = std::chrono::system_clock; -using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; - -constexpr uint32_t ITERATE_TIMES = 10000; -namespace OHOS::DistributedRdb { -RdbSyncer::RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer) - : param_(param), observer_(observer) -{ - ZLOGI("construct %{public}s", Anonymous::Change(param_.storeName_).c_str()); -} - -RdbSyncer::~RdbSyncer() noexcept -{ - param_.password_.assign(param_.password_.size(), 0); - ZLOGI("destroy %{public}s", Anonymous::Change(param_.storeName_).c_str()); - if ((manager_ != nullptr) && (delegate_ != nullptr)) { - manager_->CloseStore(delegate_); - } - delete manager_; - if (observer_ != nullptr) { - delete observer_; - } -} - -void RdbSyncer::SetTimerId(uint64_t timerId) -{ - timerId_ = timerId; -} - -uint64_t RdbSyncer::GetTimerId() const -{ - return timerId_; -} - -pid_t RdbSyncer::GetPid() const -{ - return pid_; -} - -std::string RdbSyncer::GetIdentifier() const -{ - return DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier(GetUserId(), GetAppId(), GetStoreId()); -} - -std::string RdbSyncer::GetUserId() const -{ - return std::to_string(AccountDelegate::GetInstance()->GetUserByToken(token_)); -} - -std::string RdbSyncer::GetBundleName() const -{ - return param_.bundleName_; -} - -std::string RdbSyncer::GetAppId() const -{ - return DistributedData::CheckerManager::GetInstance().GetAppId({ uid_, token_, param_.bundleName_ }); -} - -std::string RdbSyncer::GetStoreId() const -{ - return RemoveSuffix(param_.storeName_); -} - -int32_t RdbSyncer::Init(pid_t pid, pid_t uid, uint32_t token, const StoreMetaData &meta) -{ - ZLOGI("enter"); - pid_ = pid; - uid_ = uid; - token_ = token; - - if (InitDBDelegate(meta) != RDB_OK) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } - - ZLOGI("success"); - return RDB_OK; -} - -bool RdbSyncer::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password) -{ - if (!metaData.isEncrypt) { - return true; - } - - std::string key = metaData.GetSecretKey(); - DistributedData::SecretKeyMetaData secretKeyMeta; - MetaDataManager::GetInstance().LoadMeta(key, secretKeyMeta, true); - std::vector decryptKey; - CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); - if (password.SetValue(decryptKey.data(), decryptKey.size()) != DistributedDB::CipherPassword::OK) { - std::fill(decryptKey.begin(), decryptKey.end(), 0); - ZLOGE("Set secret key value failed. len is (%{public}d)", int32_t(decryptKey.size())); - return false; - } - std::fill(decryptKey.begin(), decryptKey.end(), 0); - return true; -} - -std::string RdbSyncer::RemoveSuffix(const std::string& name) -{ - std::string suffix(".db"); - auto pos = name.rfind(suffix); - if (pos == std::string::npos || pos < name.length() - suffix.length()) { - return name; - } - return std::string(name, 0, pos); -} - -int32_t RdbSyncer::InitDBDelegate(const StoreMetaData &meta) -{ - std::lock_guard lock(mutex_); - if (manager_ == nullptr) { - manager_ = new(std::nothrow) DistributedDB::RelationalStoreManager(meta.appId, meta.user, meta.instanceId); - } - if (manager_ == nullptr) { - ZLOGE("malloc manager failed"); - return RDB_ERROR; - } - - if (delegate_ == nullptr) { - DistributedDB::RelationalStoreDelegate::Option option; - if (meta.isEncrypt) { - GetPassword(meta, option.passwd); - option.isEncryptedDb = param_.isEncrypt_; - option.iterateTimes = ITERATE_TIMES; - option.cipher = DistributedDB::CipherType::AES_256_GCM; - } - option.observer = observer_; - std::string fileName = meta.dataDir; - ZLOGI("path=%{public}s storeId=%{public}s", Anonymous::Change(fileName).c_str(), meta.GetStoreAlias().c_str()); - auto status = manager_->OpenStore(fileName, meta.storeId, option, delegate_); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("open store failed, path=%{public}s storeId=%{public}s status=%{public}d", - Anonymous::Change(fileName).c_str(), meta.GetStoreAlias().c_str(), status); - return RDB_ERROR; - } - ZLOGI("open store success"); - } - - return RDB_OK; -} - -std::pair RdbSyncer::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName) -{ - if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { - return { 0, 0 }; - } - - HapTokenInfo tokenInfo; - tokenInfo.instIndex = -1; - int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); - if (errCode != RET_SUCCESS) { - ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId, - bundleName.c_str()); - return { -1, -1 }; - } - return { tokenInfo.instIndex, tokenInfo.userID }; -} - -DistributedDB::RelationalStoreDelegate* RdbSyncer::GetDelegate() -{ - std::lock_guard lock(mutex_); - return delegate_; -} - -int32_t RdbSyncer::SetDistributedTables(const std::vector &tables, int32_t type) -{ - auto* delegate = GetDelegate(); - if (delegate == nullptr) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } - - for (const auto& table : tables) { - ZLOGI("%{public}s", table.c_str()); - auto dBStatus = delegate->CreateDistributedTable(table, static_cast(type)); - if (dBStatus != DistributedDB::DBStatus::OK) { - ZLOGE("create distributed table failed, table:%{public}s, err:%{public}d", table.c_str(), dBStatus); - return RDB_ERROR; - } - } - ZLOGI("create distributed table success"); - return RDB_OK; -} - -std::vector RdbSyncer::GetConnectDevices() -{ - auto deviceInfos = DmAdapter::GetInstance().GetRemoteDevices(); - std::vector devices; - for (const auto& deviceInfo : deviceInfos) { - devices.push_back(deviceInfo.networkId); - } - ZLOGI("size=%{public}u", static_cast(devices.size())); - for (const auto& device: devices) { - ZLOGI("%{public}s", Anonymous::Change(device).c_str()); - } - return devices; -} - -std::vector RdbSyncer::NetworkIdToUUID(const std::vector &networkIds) -{ - std::vector uuids; - for (const auto& networkId : networkIds) { - auto uuid = DmAdapter::GetInstance().GetUuidByNetworkId(networkId); - if (uuid.empty()) { - ZLOGE("%{public}s failed", Anonymous::Change(networkId).c_str()); - continue; - } - uuids.push_back(uuid); - ZLOGI("%{public}s <--> %{public}s", Anonymous::Change(networkId).c_str(), Anonymous::Change(uuid).c_str()); - } - return uuids; -} - -Details RdbSyncer::HandleSyncStatus(const std::map> &syncStatus) -{ - Details details; - for (const auto& status : syncStatus) { - auto res = DistributedDB::DBStatus::OK; - for (const auto& tableStatus : status.second) { - if (tableStatus.status != DistributedDB::DBStatus::OK) { - res = tableStatus.status; - break; - } - } - std::string uuid = DmAdapter::GetInstance().ToNetworkID(status.first); - if (uuid.empty()) { - ZLOGE("%{public}.6s failed", status.first.c_str()); - continue; - } - ZLOGI("%{public}.6s=%{public}d", uuid.c_str(), res); - details[uuid].progress = SYNC_FINISH; - details[uuid].code = int32_t(res); - } - return details; -} - -Details RdbSyncer::HandleGenDetails(const GenDetails &details) -{ - Details dbDetails; - for (const auto& [id, detail] : details) { - auto &dbDetail = dbDetails[id]; - dbDetail.progress = detail.progress; - dbDetail.code = detail.code; - for (auto &[name, table] : detail.details) { - auto &dbTable = dbDetail.details[name]; - Constant::Copy(&dbTable, &table); - } - } - return dbDetails; -} - -void RdbSyncer::EqualTo(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - query.EqualTo(operation.field_, operation.values_[0]); - ZLOGI("field=%{public}s value=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); -} - -void RdbSyncer::NotEqualTo(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - query.NotEqualTo(operation.field_, operation.values_[0]); - ZLOGI("field=%{public}s value=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); -} - -void RdbSyncer::And(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - query.And(); - ZLOGI(""); -} - -void RdbSyncer::Or(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - query.Or(); - ZLOGI(""); -} - -void RdbSyncer::OrderBy(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - bool isAsc = operation.values_[0] == "true"; - query.OrderBy(operation.field_, isAsc); - ZLOGI("field=%{public}s isAsc=%{public}s", operation.field_.c_str(), operation.values_[0].c_str()); -} - -void RdbSyncer::Limit(const RdbPredicateOperation &operation, DistributedDB::Query &query) -{ - char *end = nullptr; - int limit = static_cast(strtol(operation.field_.c_str(), &end, DECIMAL_BASE)); - int offset = static_cast(strtol(operation.values_[0].c_str(), &end, DECIMAL_BASE)); - if (limit < 0) { - limit = 0; - } - if (offset < 0) { - offset = 0; - } - query.Limit(limit, offset); - ZLOGI("limit=%{public}d offset=%{public}d", limit, offset); -} - -DistributedDB::Query RdbSyncer::MakeQuery(const PredicatesMemo &predicates) -{ - ZLOGI("table=%{public}zu", predicates.tables_.size()); - auto query = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin()) - : DistributedDB::Query::Select(); - if (predicates.tables_.size() > 1) { - query.FromTable(predicates.tables_); - } - for (const auto& operation : predicates.operations_) { - if (operation.operator_ >= 0 && operation.operator_ < OPERATOR_MAX) { - HANDLES[operation.operator_](operation, query); - } - } - return query; -} - -int32_t RdbSyncer::DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) -{ - ZLOGI("enter"); - auto* delegate = GetDelegate(); - if (delegate == nullptr) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } - - if (option.mode < DistributedData::GeneralStore::NEARBY_END) { - auto &networkIds = predicates.devices_; - auto devices = networkIds.empty() ? NetworkIdToUUID(GetConnectDevices()) : NetworkIdToUUID(networkIds); - return delegate->Sync( - devices, static_cast(option.mode), MakeQuery(predicates), - [async](const std::map> &syncStatus) { - if (async != nullptr) { - async(HandleSyncStatus(syncStatus)); - } - }, - !option.isAsync); - } else if (option.mode < DistributedData::GeneralStore::CLOUD_END && - option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) { - CloudEvent::StoreInfo storeInfo; - storeInfo.bundleName = GetBundleName(); - storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(token_); - storeInfo.storeName = GetStoreId(); - storeInfo.tokenId = token_; - std::shared_ptr query = nullptr; - if (!predicates.tables_.empty()) { - query = std::make_shared(); - query->query_.FromTable(predicates.tables_); - } - - auto info = ChangeEvent::EventInfo(option.mode, (option.isAsync ? 0 : WAIT_TIME), - (option.isAsync && option.seqNum == 0), query, [async](const GenDetails &details) { - async(HandleGenDetails(details)); - }); - auto evt = std::make_unique(std::move(storeInfo), std::move(info)); - EventCenter::GetInstance().PostEvent(std::move(evt)); - } - ZLOGI("delegate sync"); - return RDB_OK; -} - -int32_t RdbSyncer::RemoteQuery(const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet) -{ - ZLOGI("enter"); - auto* delegate = GetDelegate(); - if (delegate == nullptr) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } - - ZLOGI("delegate remote query"); - std::shared_ptr dbResultSet; - DistributedDB::DBStatus status = delegate->RemoteQuery(device, {sql, selectionArgs}, - REMOTE_QUERY_TIME_OUT, dbResultSet); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("DistributedDB remote query failed, status is %{public}d.", status); - return RDB_ERROR; - } - resultSet = new (std::nothrow) RdbResultSetImpl(dbResultSet); - if (resultSet == nullptr) { - ZLOGE("resultSet is nullptr"); - return RDB_ERROR; - } - return RDB_OK; -} - -int32_t RdbSyncer::RemoveDeviceData() -{ - auto* delegate = GetDelegate(); - if (delegate == nullptr) { - ZLOGE("delegate is nullptr"); - return RDB_ERROR; - } - DistributedDB::DBStatus status = delegate->RemoveDeviceData(); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("DistributedDB RemoveDeviceData failed, status is %{public}d.", status); - return RDB_ERROR; - } - return RDB_OK; -} -} // namespace OHOS::DistributedRdb diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h deleted file mode 100644 index 11983e8d..00000000 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DISTRIBUTED_RDB_SYNCER_H -#define DISTRIBUTED_RDB_SYNCER_H - -#include -#include -#include - -#include "iremote_object.h" -#include "metadata/secret_key_meta_data.h" -#include "metadata/store_meta_data.h" -#include "rdb_service.h" -#include "rdb_store_observer_impl.h" -#include "rdb_types.h" -#include "relational_store_delegate.h" -#include "relational_store_manager.h" -#include "store/general_value.h" -namespace OHOS::DistributedRdb { -class RdbSyncer { -public: - using StoreMetaData = OHOS::DistributedData::StoreMetaData; - using GenDetails = OHOS::DistributedData::GenDetails; - using SecretKeyMetaData = DistributedData::SecretKeyMetaData; - using Option = DistributedRdb::RdbService::Option; - RdbSyncer(const RdbSyncerParam& param, RdbStoreObserverImpl* observer); - ~RdbSyncer() noexcept; - - int32_t Init(pid_t pid, pid_t uid, uint32_t token, const StoreMetaData &meta); - - pid_t GetPid() const; - - void SetTimerId(uint64_t timerId); - - uint64_t GetTimerId() const; - - std::string GetStoreId() const; - - std::string GetIdentifier() const; - - int32_t SetDistributedTables(const std::vector &tables, int32_t type); - - int32_t DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); - - int32_t RemoteQuery(const std::string& device, const std::string& sql, - const std::vector& selectionArgs, sptr& resultSet); - - int32_t RemoveDeviceData(); - - static std::string RemoveSuffix(const std::string& name); - - static std::pair GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName); - - static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); - - static DistributedDB::Query MakeQuery(const PredicatesMemo &predicates); - -private: - std::string GetUserId() const; - - std::string GetBundleName() const; - - std::string GetAppId() const; - - int32_t InitDBDelegate(const StoreMetaData &meta); - - DistributedDB::RelationalStoreDelegate* GetDelegate(); - - std::mutex mutex_; - DistributedDB::RelationalStoreManager* manager_ {}; - DistributedDB::RelationalStoreDelegate* delegate_ {}; - RdbSyncerParam param_; - RdbStoreObserverImpl *observer_ {}; - pid_t pid_ {}; - pid_t uid_ {}; - uint32_t token_ {}; - uint64_t timerId_ {}; - - static std::vector GetConnectDevices(); - static std::vector NetworkIdToUUID(const std::vector& networkIds); - - static Details HandleSyncStatus(const std::map> &syncStatus); - static Details HandleGenDetails(const GenDetails &details); - static void EqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static void NotEqualTo(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static void And(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static void Or(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static void OrderBy(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static void Limit(const RdbPredicateOperation& operation, DistributedDB::Query& query); - - using PredicateHandle = void(*)(const RdbPredicateOperation& operation, DistributedDB::Query& query); - static inline PredicateHandle HANDLES[OPERATOR_MAX] = { - [EQUAL_TO] = &RdbSyncer::EqualTo, - [NOT_EQUAL_TO] = &RdbSyncer::NotEqualTo, - [AND] = &RdbSyncer::And, - [OR] = &RdbSyncer::Or, - [ORDER_BY] = &RdbSyncer::OrderBy, - [LIMIT] = &RdbSyncer::Limit, - }; - - static constexpr int DECIMAL_BASE = 10; - static constexpr uint64_t REMOTE_QUERY_TIME_OUT = 30 * 1000; - static constexpr int32_t WAIT_TIME = 30 * 1000; -}; -} // namespace OHOS::DistributedRdb -#endif diff --git a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp index 23bac1a7..b2be4ffa 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp @@ -115,6 +115,22 @@ ValueProxy::Buckets ValueProxy::Convert(DistributedData::VBuckets &&buckets) return proxy; } +ValueProxy::Value ValueProxy::Convert(DistributedDB::VariantData &&value) +{ + Value proxy; + DistributedData::Convert(std::move(value), proxy.value_); + return proxy; +} + +ValueProxy::Bucket ValueProxy::Convert(std::map &&value) +{ + ValueProxy::Bucket proxy; + for (auto &[key, value] : value) { + proxy.value_.insert_or_assign(key, Convert(std::move(value))); + } + return proxy; +} + ValueProxy::Asset::Asset(DistributedData::Asset asset) { asset_ = std::move(asset); @@ -205,6 +221,9 @@ ValueProxy::Asset::operator DistributedDB::Asset() uint32_t ValueProxy::Asset::ConvertToDataStatus(const DistributedDB::Asset &asset) { if (asset.status == DistributedDB::AssetStatus::DOWNLOADING) { + if (asset.flag == static_cast(DistributedDB::AssetOpType::DELETE)) { + return DistributedData::Asset::STATUS_DELETE; + } return DistributedData::Asset::STATUS_DOWNLOADING; } else if (asset.status == DistributedDB::AssetStatus::ABNORMAL) { return DistributedData::Asset::STATUS_ABNORMAL; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h index 3c351ee5..272f78a9 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.h @@ -20,6 +20,7 @@ #include "store/general_value.h" #include "value_object.h" #include "values_bucket.h" +#include "distributeddb/result_set.h" namespace OHOS::DistributedRdb { class ValueProxy final { public: @@ -190,6 +191,7 @@ public: friend ValueProxy; std::vector value_; }; + static Value Convert(DistributedData::Value &&value); static Value Convert(NativeRdb::ValueObject &&value); static Value Convert(DistributedDB::Type &&value); @@ -202,6 +204,9 @@ public: static Buckets Convert(std::vector &&buckets); static Buckets Convert(std::vector &&buckets); + static Value Convert(DistributedDB::VariantData &&value); + static Bucket Convert(std::map &&value); + template static std::enable_if_t < CVT_INDEX Convert(const std::map &values) @@ -213,6 +218,18 @@ public: return bucket; } + template + static std::enable_if_t < CVT_INDEX + Convert(const std::vector &values) + { + Values proxy; + proxy.value_.resize(values.size()); + for (size_t i = 0; i < values.size(); i++) { + proxy.value_[i].value_ = static_cast, Proxy>>(values[i]); + } + return proxy; + } + private: ValueProxy() = delete; ~ValueProxy() = delete; diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index a951e052..9f814f58 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -203,6 +203,43 @@ ohos_unittest("DeviceMatrixTest") { ] } +ohos_unittest("RdbResultSetImplTest") { + module_out_path = module_output_path + sources = [ + "${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/value_proxy.cpp", + "mock/cursor_mock.cpp", + "rdb_result_set_impl_test.cpp", + ] + + include_dirs = [ + "${data_service_path}/service/rdb", + "${relational_store_path}/interfaces/inner_api/cloud_data/include", + "${relational_store_path}/interfaces/inner_api/rdb/include", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_distributeddb_path}:distributeddb", + "//third_party/googletest:gtest_main", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -215,6 +252,7 @@ group("unittest") { ":CryptoManagerTest", ":DeviceMatrixTest", ":DirectoryManagerTest", + ":RdbResultSetImplTest", ":ValueProxyTest", ] } 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 d39a5b82..45818b82 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 @@ -71,8 +71,6 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${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_store_observer_impl.cpp", - "${data_service_path}/service/rdb/rdb_syncer.cpp", "${data_service_path}/service/rdb/rdb_watcher.cpp", "${data_service_path}/service/rdb/value_proxy.cpp", "cloudservicestub_fuzzer.cpp", @@ -92,6 +90,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "ability_runtime:ability_manager", "ability_runtime:dataobs_manager", "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", "access_token:libtokenid_sdk", "c_utils:utils", "device_auth:deviceauth_sdk", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp index 1dada5ad..9f8ad713 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/cloudservicestub_fuzzer/cloudservicestub_fuzzer.cpp @@ -18,26 +18,69 @@ #include #include +#include "accesstoken_kit.h" #include "cloud_service_impl.h" +#include "ipc_skeleton.h" #include "message_parcel.h" #include "securec.h" +#include "token_setproc.h" using namespace OHOS::CloudData; +using namespace OHOS::Security::AccessToken; namespace OHOS { +constexpr int USER_ID = 100; +constexpr int INST_INDEX = 0; const std::u16string INTERFACE_TOKEN = u"OHOS.CloudData.CloudServer"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 4; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 4; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; + +void AllocAndSetHapToken() +{ + HapInfoParams info = { + .userID = USER_ID, + .bundleName = "ohos.test.demo", + .instIndex = INST_INDEX, + .appIDDesc = "ohos.test.demo", + .isSystemApp = true + }; + + HapPolicyParams policy = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = {}, + .permStateList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } + }; + auto tokenID = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(tokenID.tokenIDEx); +} bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { + std::shared_ptr cloudServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + cloudServiceImpl->OnBind( + { "CloudServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + + AllocAndSetHapToken(); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - std::shared_ptr cloudServiceStub = std::make_shared(); + std::shared_ptr cloudServiceStub = cloudServiceImpl; cloudServiceStub->OnRemoteRequest(code, request, reply); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn index e2cbf7fe..8722e074 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -46,10 +46,12 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { sources = [ "${data_service_path}/service/data_share/common/app_connect_manager.cpp", + "${data_service_path}/service/data_share/common/base64_utils.cpp", "${data_service_path}/service/data_share/common/bundle_mgr_proxy.cpp", "${data_service_path}/service/data_share/common/db_delegate.cpp", "${data_service_path}/service/data_share/common/div_strategy.cpp", "${data_service_path}/service/data_share/common/extension_connect_adaptor.cpp", + "${data_service_path}/service/data_share/common/extension_mgr_proxy.cpp", "${data_service_path}/service/data_share/common/kv_delegate.cpp", "${data_service_path}/service/data_share/common/rdb_delegate.cpp", "${data_service_path}/service/data_share/common/scheduler_manager.cpp", @@ -97,13 +99,14 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { external_deps = [ "ability_base:want", "ability_base:zuri", - "ability_runtime:ability_manager", "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", + "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "device_manager:devicemanagersdk", "hilog:libhilog", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp index 7fb0269f..f077c324 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/datashareservicestub_fuzzer.cpp @@ -19,25 +19,33 @@ #include #include "data_share_service_impl.h" +#include "ipc_skeleton.h" #include "message_parcel.h" #include "securec.h" using namespace OHOS::DataShare; namespace OHOS { -const std::u16string INTERFACE_TOKEN = u"OHOS.DataShare.IDataShare"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 16; +const std::u16string INTERFACE_TOKEN = u"OHOS.DataShare.IDataShareService"; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 16; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { + std::shared_ptr dataShareServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + dataShareServiceImpl->OnBind( + { "DataShareServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - std::shared_ptr dataShareServiceStub = std::make_shared(); + std::shared_ptr dataShareServiceStub = dataShareServiceImpl; dataShareServiceStub->OnRemoteRequest(code, request, reply); return true; } 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 8998072c..01f380c6 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 @@ -21,6 +21,7 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { include_dirs = [ "${data_service_path}/adapter/include", + "${data_service_path}/app/src/checker", "${data_service_path}/app/src", "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", @@ -51,6 +52,8 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/app/src/checker/bundle_checker.cpp", + "${data_service_path}/app/src/checker/system_checker.cpp", "${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", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp index b01aa999..ebbc8220 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/kvdbservicestub_fuzzer/kvdbservicestub_fuzzer.cpp @@ -12,32 +12,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "kvdbservicestub_fuzzer.h" #include #include +#include "bootstrap.h" +#include "ipc_skeleton.h" #include "kvdb_service_impl.h" #include "message_parcel.h" #include "securec.h" +using namespace OHOS::DistributedData; using namespace OHOS::DistributedKv; namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedKv.KVFeature"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 16; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 16; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { + std::shared_ptr kvdbServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + kvdbServiceImpl->OnBind( + { "KvdbServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + + Bootstrap::GetInstance().LoadComponents(); + Bootstrap::GetInstance().LoadDirectory(); + Bootstrap::GetInstance().LoadCheckers(); + Bootstrap::GetInstance().LoadNetworks(); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - std::shared_ptr kvdbServiceStub = std::make_shared(); + std::shared_ptr kvdbServiceStub = kvdbServiceImpl; kvdbServiceStub->OnRemoteRequest(code, request, reply); return true; } 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 2db37d6e..cd27ac04 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 @@ -25,15 +25,9 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", "${data_service_path}/service/bootstrap/include", - "${data_service_path}/service/cloud", "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", - "${data_service_path}/service/data_share", - "${data_service_path}/service/kvdb", - "${data_service_path}/service/matrix/include", "${data_service_path}/service/object", - "${data_service_path}/service/permission/include", - "${data_service_path}/service/rdb", "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", @@ -56,6 +50,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { ] sources = [ + "${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/backup_config.cpp", @@ -66,14 +61,11 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${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/object/object_callback_proxy.cpp", "${data_service_path}/service/object/object_data_listener.cpp", "${data_service_path}/service/object/object_manager.cpp", "${data_service_path}/service/object/object_service_impl.cpp", "${data_service_path}/service/object/object_service_stub.cpp", - "${data_service_path}/service/permission/src/permit_delegate.cpp", "objectservicestub_fuzzer.cpp", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp index 410f53b1..64b22df0 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/objectservicestub_fuzzer/objectservicestub_fuzzer.cpp @@ -18,6 +18,7 @@ #include #include +#include "ipc_skeleton.h" #include "object_service_impl.h" #include "message_parcel.h" #include "securec.h" @@ -26,18 +27,25 @@ using namespace OHOS::DistributedObject; namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedObject.IObjectService"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 4; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 4; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { + std::shared_ptr objectServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + objectServiceImpl->OnBind( + { "ObjectServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - std::shared_ptr objectServiceStub = std::make_shared(); + std::shared_ptr objectServiceStub = objectServiceImpl; objectServiceStub->OnRemoteRequest(code, request, reply); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn index 494fd1c0..c8736f9f 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/BUILD.gn @@ -23,16 +23,6 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "${data_service_path}/adapter/include", "${data_service_path}/app/src", "${data_service_path}/framework/include", - "${data_service_path}/service/backup/include", - "${data_service_path}/service/bootstrap/include", - "${data_service_path}/service/cloud", - "${data_service_path}/service/config/include", - "${data_service_path}/service/crypto/include", - "${data_service_path}/service/data_share", - "${data_service_path}/service/kvdb", - "${data_service_path}/service/matrix/include", - "${data_service_path}/service/object", - "${data_service_path}/service/permission/include", "${data_service_path}/service/rdb", "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", @@ -41,7 +31,6 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { "${kv_store_distributeddb_path}/include/", "${kv_store_distributeddb_path}/interfaces/include/", "${kv_store_distributeddb_path}/interfaces/include/relational", - "${dataobject_path}/frameworks/innerkitsimpl/include", "${relational_store_path}/interfaces/inner_api/cloud_data/include", "${relational_store_path}/interfaces/inner_api/rdb/include", "//third_party/json/single_include", @@ -58,33 +47,8 @@ ohos_fuzztest("RdbResultSetStubFuzzTest") { ] sources = [ - "${data_service_path}/service/bootstrap/src/bootstrap.cpp", - "${data_service_path}/service/config/src/config_factory.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/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/permission/src/permit_delegate.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_store_observer_impl.cpp", - "${data_service_path}/service/rdb/rdb_syncer.cpp", - "${data_service_path}/service/rdb/rdb_watcher.cpp", "${data_service_path}/service/rdb/value_proxy.cpp", "rdbresultsetstub_fuzzer.cpp", ] diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp index a1542122..288cb24d 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbresultsetstub_fuzzer/rdbresultsetstub_fuzzer.cpp @@ -20,14 +20,15 @@ #include "rdb_result_set_impl.h" #include "message_parcel.h" +#include "store/cursor.h" #include "securec.h" using namespace OHOS::DistributedRdb; namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS::NativeRdb.IResultSet"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 24; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 24; bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { @@ -38,7 +39,7 @@ bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) request.RewindRead(0); MessageParcel reply; MessageOption option; - std::shared_ptr dbResultSet; + std::shared_ptr dbResultSet; std::shared_ptr rdbResultSetStub = std::make_shared(dbResultSet); rdbResultSetStub->OnRemoteRequest(code, request, reply, option); return true; 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 9fef0947..b0c3923a 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,8 +69,6 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${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_store_observer_impl.cpp", - "${data_service_path}/service/rdb/rdb_syncer.cpp", "${data_service_path}/service/rdb/rdb_watcher.cpp", "${data_service_path}/service/rdb/value_proxy.cpp", "rdbservicestub_fuzzer.cpp", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp index aa7737e8..3990a55b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/rdbservicestub_fuzzer/rdbservicestub_fuzzer.cpp @@ -18,6 +18,7 @@ #include #include +#include "ipc_skeleton.h" #include "rdb_service_impl.h" #include "message_parcel.h" #include "securec.h" @@ -26,18 +27,25 @@ using namespace OHOS::DistributedRdb; namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS.DistributedRdb.IRdbService"; -const uint32_t CODE_MIN = 0; -const uint32_t CODE_MAX = 10; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 10; +constexpr size_t NUM_MIN = 5; +constexpr size_t NUM_MAX = 12; bool OnRemoteRequestFuzz(const uint8_t *data, size_t size) { + std::shared_ptr rdbServiceImpl = std::make_shared(); + std::shared_ptr executor = std::make_shared(NUM_MAX, NUM_MIN); + rdbServiceImpl->OnBind( + { "RdbServiceStubFuzz", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - std::shared_ptr rdbServiceStub = std::make_shared(); + std::shared_ptr rdbServiceStub = rdbServiceImpl; rdbServiceStub->OnRemoteRequest(code, request, reply); return true; } diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp index 010f5bda..3e6235bd 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/udmfservice_fuzzer/udmfservice_fuzzer.cpp @@ -26,10 +26,12 @@ using namespace OHOS::UDMF; namespace OHOS { const std::u16string INTERFACE_TOKEN = u"OHOS.UDMF.UdmfService"; +constexpr uint32_t CODE_MIN = 0; +constexpr uint32_t CODE_MAX = 10; bool OnRemoteRequestFuzz(const uint8_t* data, size_t size) { - uint32_t code = static_cast(*data); + uint32_t code = static_cast(*data) % (CODE_MAX - CODE_MIN + 1) + CODE_MIN; MessageParcel request; request.WriteInterfaceToken(INTERFACE_TOKEN); request.WriteBuffer(data, size); diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp new file mode 100644 index 00000000..a11612e2 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cursor_mock.h" +#include "store/general_value.h" +namespace OHOS { +namespace DistributedData { +CursorMock::CursorMock(std::shared_ptr resultSet) : resultSet_(std::move(resultSet)) {} +CursorMock::~CursorMock() {} +int32_t CursorMock::GetColumnNames(std::vector &names) const +{ + if (!resultSet_->empty()) { + for (auto &[key, value] : *resultSet_->begin()) { + names.push_back(key); + } + } + return GeneralError::E_OK; +} + +int32_t CursorMock::GetColumnName(int32_t col, std::string &name) const +{ + if (!resultSet_->empty()) { + int index = 0; + for (auto &[key, value] : *resultSet_->begin()) { + if (index++ == col) { + name = key; + break; + } + } + } + return GeneralError::E_OK; +} + +int32_t CursorMock::GetColumnType(int32_t col) const +{ + if (!resultSet_->empty()) { + int index = 0; + for (auto &[key, value] : *resultSet_->begin()) { + if (index++ == col) { + return value.index(); + } + } + } + return GeneralError::E_OK; +} + +int32_t CursorMock::GetCount() const +{ + return resultSet_->size(); +} + +int32_t CursorMock::MoveToFirst() +{ + index_ = 0; + return GeneralError::E_OK; +} + +int32_t CursorMock::MoveToNext() +{ + index_++; + return GeneralError::E_OK; +} + +int32_t CursorMock::MoveToPrev() +{ + index_--; + return GeneralError::E_OK; +} + +int32_t CursorMock::GetEntry(DistributedData::VBucket &entry) +{ + return GeneralError::E_NOT_SUPPORT; +} + +int32_t CursorMock::GetRow(DistributedData::VBucket &data) +{ + if (index_ >= 0 && index_ < resultSet_->size()) { + data = (*resultSet_)[index_]; + } + return GeneralError::E_OK; +} + +int32_t CursorMock::Get(int32_t col, DistributedData::Value &value) +{ + if (index_ >= 0 && index_ < resultSet_->size()) { + int i = 0; + for (auto &[k, v] : (*resultSet_)[index_]) { + if (i++ == col) { + value = v; + break; + } + } + } + return GeneralError::E_OK; +} + +int32_t CursorMock::Get(const std::string &col, DistributedData::Value &value) +{ + if (index_ >= 0 && index_ < resultSet_->size()) { + for (auto &[k, v] : (*resultSet_)[index_]) { + if (k == col) { + value = v; + break; + } + } + } + return GeneralError::E_OK; +} + +int32_t CursorMock::Close() +{ + resultSet_->clear(); + return GeneralError::E_OK; +} + +bool CursorMock::IsEnd() +{ + return index_ == resultSet_->size() - 1; +} +} // namespace DistributedData +} // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.h new file mode 100644 index 00000000..ca487f14 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CURSOR_MOCK_H +#define OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CURSOR_MOCK_H +#include +#include +#include +#include "store/cursor.h" +#include "store/general_value.h" +namespace OHOS { +namespace DistributedData { +class CursorMock : public DistributedData::Cursor { +public: + using ResultSet = std::vector>; + explicit CursorMock(std::shared_ptr resultSet); + ~CursorMock(); + int32_t GetColumnNames(std::vector &names) const override; + int32_t GetColumnName(int32_t col, std::string &name) const override; + int32_t GetColumnType(int32_t col) const override; + int32_t GetCount() const override; + int32_t MoveToFirst() override; + int32_t MoveToNext() override; + int32_t MoveToPrev() override; + int32_t GetEntry(DistributedData::VBucket &entry) override; + int32_t GetRow(DistributedData::VBucket &data) override; + int32_t Get(int32_t col, DistributedData::Value &value) override; + int32_t Get(const std::string &col, DistributedData::Value &value) override; + int32_t Close() override; + bool IsEnd() override; + +private: + std::shared_ptr resultSet_; + int32_t index_ = 0; +}; +} // namespace DistributedData +} // namespace OHOS +#endif // OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CURSOR_MOCK_H diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp new file mode 100644 index 00000000..1e6f9036 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" +#include "mock/cursor_mock.h" +#include "rdb_result_set_impl.h" +#include "store/cursor.h" +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; + +namespace OHOS::Test { +namespace DistributedRDBTest { +class RdbResultSetImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline const std::vector> Names = { + { "1_id", RdbResultSetImpl::ColumnType::TYPE_INTEGER }, + { "2_name", RdbResultSetImpl::ColumnType::TYPE_STRING }, + { "3_price", RdbResultSetImpl::ColumnType::TYPE_FLOAT }, + { "4_bool", RdbResultSetImpl::ColumnType::TYPE_INTEGER }, + { "5_bytes", RdbResultSetImpl::ColumnType::TYPE_BLOB } + }; + static std::map makeEntry(int i); + static RdbResultSetImpl::ColumnType getColumnType(std::string &name); + std::shared_ptr cursor; + std::shared_ptr resultSet; + static inline constexpr int32_t SIZE = 50; +}; + +void RdbResultSetImplTest::SetUpTestCase(void) {} + +void RdbResultSetImplTest::TearDownTestCase(void) {} + +void RdbResultSetImplTest::SetUp() +{ + cursor = std::make_shared(SIZE); + for (int i = 0; i < SIZE; i++) { + (*cursor)[i] = makeEntry(i); + } + auto cursorMock = std::make_shared(cursor); + resultSet = std::make_shared(cursorMock); +} + +void RdbResultSetImplTest::TearDown() {} + +std::map RdbResultSetImplTest::makeEntry(int i) +{ + std::string str = "RdbResultSetImplTest"; + Bytes bytes(str.begin(), str.end()); + std::map entry = { + { Names[0].first, i }, + { Names[1].first, "name_" + std::to_string(i) }, + { Names[2].first, 1.65 }, + { Names[3].first, i & 0x1 }, + { Names[4].first, bytes} + }; + return entry; +} + +RdbResultSetImpl::ColumnType RdbResultSetImplTest::getColumnType(string &name) +{ + RdbResultSetImpl::ColumnType columnType = RdbResultSetImpl::ColumnType::TYPE_NULL; + std::find_if(Names.begin(), Names.end(), [&columnType, &name](auto &pr) { + if (pr.first == name) { + columnType = pr.second; + return true; + } + return false; + }); + return columnType; +} + +/** +* @tc.name: RdbResultSetImplGetColumn +* @tc.desc: RdbResultSetImpl get col; +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGetColumn, TestSize.Level0) +{ + std::vector names; + resultSet->GetAllColumnNames(names); + ASSERT_EQ(Names.size(), names.size()); + for (int i = 0; i < Names.size(); i++) { + ASSERT_EQ(Names[i].first, names[i]); + std::string colName; + ASSERT_EQ(resultSet->GetColumnName(i, colName), NativeRdb::E_OK); + ASSERT_EQ(colName, names[i]); + RdbResultSetImpl::ColumnType columnType; + ASSERT_EQ(resultSet->GetColumnType(i, columnType), NativeRdb::E_OK); + ASSERT_EQ(columnType, getColumnType(colName)); + } +} + +/** +* @tc.name: RdbResultSetImplGoTO +* @tc.desc: RdbResultSetImpl go to row; +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGoTO, TestSize.Level0) +{ + int count = 0; + ASSERT_EQ(resultSet->GetRowCount(count), NativeRdb::E_OK); + ASSERT_EQ(count, SIZE); + + int position = 0; + ASSERT_EQ(resultSet->GoToFirstRow(), NativeRdb::E_OK); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, 0); + + bool result; + ASSERT_EQ(resultSet->IsStarted(result), NativeRdb::E_OK); + ASSERT_FALSE(result); + + ASSERT_EQ(resultSet->GoToPreviousRow(), NativeRdb::E_ERROR); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, -1); + + ASSERT_EQ(resultSet->IsStarted(result), NativeRdb::E_OK); + ASSERT_TRUE(result); + + int absPosition = random() % SIZE; + ASSERT_EQ(resultSet->GoToRow(absPosition), NativeRdb::E_OK); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, absPosition); + + ASSERT_EQ(resultSet->GoToLastRow(), NativeRdb::E_OK); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, SIZE - 1); + + ASSERT_EQ(resultSet->IsEnded(result), NativeRdb::E_OK); + ASSERT_FALSE(result); + + ASSERT_EQ(resultSet->GoToNextRow(), NativeRdb::E_ERROR); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, SIZE); + + ASSERT_EQ(resultSet->IsEnded(result), NativeRdb::E_OK); + ASSERT_TRUE(result); + + ASSERT_EQ(resultSet->GoTo(-10), NativeRdb::E_OK); + ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK); + ASSERT_EQ(position, SIZE - 10); +} + +/** +* @tc.name: RdbResultSetImplGet +* @tc.desc: RdbResultSetImpl get data; +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGet, TestSize.Level0) +{ + ASSERT_EQ(resultSet->GoToFirstRow(), NativeRdb::E_OK); + bool result = false; + int index = 0; + int64_t tmpInt; + double tmpFlo; + std::string tmpStr; + Bytes tmpBlob; + while (!result) { + for (int i = 0; i < Names.size(); i++) { + auto var = (*cursor)[index][Names[i].first]; + ValueProxy::Value value = ValueProxy::Convert(std::move(var)); + switch (Names[i].second) { + case RdbResultSetImpl::ColumnType::TYPE_INTEGER: + ASSERT_EQ(resultSet->GetLong(i, tmpInt), NativeRdb::E_OK); + ASSERT_EQ(tmpInt, int64_t(value)); + break; + case RdbResultSetImpl::ColumnType::TYPE_FLOAT: + ASSERT_EQ(resultSet->GetDouble(i, tmpFlo), NativeRdb::E_OK); + ASSERT_EQ(tmpFlo, double(value)); + break; + case RdbResultSetImpl::ColumnType::TYPE_STRING: + ASSERT_EQ(resultSet->GetString(i, tmpStr), NativeRdb::E_OK); + ASSERT_EQ(tmpStr, std::string(value)); + break; + case RdbResultSetImpl::ColumnType::TYPE_BLOB: + ASSERT_EQ(resultSet->GetBlob(i, tmpBlob), NativeRdb::E_OK); + ASSERT_EQ(tmpBlob.size(), Bytes(value).size()); + break; + default: + break; + } + } + resultSet->GoToNextRow(); + index++; + resultSet->IsEnded(result); + } +} +} // namespace DistributedRDBTest +} // 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 9997263e..4e33af71 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn @@ -17,16 +17,21 @@ config("module_public_config") { visibility = [ ":*" ] include_dirs = [ - "${udmf_path}/framework/common", - "${udmf_path}/interfaces/innerkits/common", - "${udmf_path}/interfaces/innerkits/data", "${data_service_path}/framework/include", + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/dfx", "${data_service_path}/service/udmf/lifecycle", "${data_service_path}/service/udmf/permission", "${data_service_path}/service/udmf/preprocess", "${data_service_path}/service/udmf/store", "${data_service_path}/service/udmf", - "${kv_store_path}/frameworks/common", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_common_path}", + "${udmf_path}/framework/common", + "${udmf_path}/interfaces/innerkits/common", + "${udmf_path}/interfaces/innerkits/data", ] } @@ -50,12 +55,16 @@ ohos_shared_library("udmf_server") { configs = [ ":module_public_config" ] - deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + ] external_deps = [ "ability_base:zuri", "ability_runtime:uri_permission_mgr", "access_token:libaccesstoken_sdk", + "app_file_service:remote_file_share_native", "bundle_framework:appexecfwk_core", "c_utils:utils", "hilog:libhilog", diff --git a/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp index 7b4bc0a3..4d1af700 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/data_manager.cpp @@ -22,6 +22,7 @@ #include "log_print.h" #include "preprocess_utils.h" #include "uri_permission_manager.h" +#include "uri.h" namespace OHOS { namespace UDMF { @@ -60,12 +61,20 @@ int32_t DataManager::SaveData(CustomOption &option, UnifiedData &unifiedData, st ZLOGE("Imputation failed"); return E_UNKNOWN; } - for (auto &record : unifiedData.GetRecords()) { - std::string uid = PreProcessUtils::IdGenerator(); - record->SetUid(uid); - } std::string intention = unifiedData.GetRuntime()->key.intention; + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); + if (ret != E_OK) { + ZLOGE("SetRemoteUri failed, ret: %{public}d.", ret); + return ret; + } + } + + for (const auto &record : unifiedData.GetRecords()) { + record->SetUid(PreProcessUtils::IdGenerator()); + } + auto store = storeCache_.GetStore(intention); if (store == nullptr) { ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); @@ -100,41 +109,81 @@ int32_t DataManager::RetrieveData(const QueryOption &query, UnifiedData &unified } int32_t res = store->Get(query.key, unifiedData); if (res != E_OK) { - ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str()); + ZLOGE("Get data from store failed, key: %{public}s.", query.key.c_str()); return res; } - if (unifiedData.IsEmpty()) { - return E_OK; - } + std::shared_ptr runtime = unifiedData.GetRuntime(); + if (static_cast(unifiedData.GetRecords().size()) != runtime->recordTotalNum) { + ZLOGE("Get data from DB is incomplete, key: %{public}s, expected recordsNum is %{public}u, not %{public}zu.", + query.key.c_str(), runtime->recordTotalNum, unifiedData.GetRecords().size()); + return E_NOT_FOUND; + } + CheckerManager::CheckInfo info; info.tokenId = query.tokenId; if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info)) { return E_NO_PERMISSION; } + + if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = ProcessingUri(query, unifiedData); + if (ret != E_OK) { + ZLOGE("DragUriProcessing failed. ret=%{public}d", ret); + return E_NO_PERMISSION; + } + } + + if (LifeCycleManager::GetInstance().DeleteOnGet(key) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } + PreProcessUtils::SetRemoteData(unifiedData); + return E_OK; +} + +int32_t DataManager::ProcessingUri(const QueryOption &query, UnifiedData &unifiedData) +{ + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + auto records = unifiedData.GetRecords(); + if (localDeviceId != unifiedData.GetRuntime()->deviceId) { + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + std::string remoteUri = file->GetRemoteUri(); + if (remoteUri.empty()) { + ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str()); + continue; + } + file->SetUri(remoteUri); // cross dev, need dis path. + } + } + } + std::string bundleName; if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { + ZLOGE("GetHapBundleNameByToken fail, key=%{public}s.", query.key.c_str()); return E_ERROR; } - if (runtime->createPackage != bundleName) { - auto records = unifiedData.GetRecords(); - for (auto record : records) { - auto type = record->GetType(); - std::string uri = ""; - if (type == UDType::FILE || type == UDType::IMAGE || type == UDType::VIDEO || type == UDType::AUDIO - || type == UDType::FOLDER) { - auto file = static_cast(record.get()); - uri = file->GetUri(); + for (auto record : records) { + if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + if (file->GetUri().empty()) { + ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str()); + continue; + } + Uri uri(file->GetUri()); + if (uri.GetAuthority().empty()) { + ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str()); + continue; } - if (!uri.empty() && (UriPermissionManager::GetInstance().GrantUriPermission(uri, bundleName) != E_OK)) { + if (UriPermissionManager::GetInstance().GrantUriPermission(file->GetUri(), bundleName) != E_OK) { + ZLOGE("GrantUriPermission fail, uriAuthority=%{public}s, bundleName=%{public}s, key=%{public}s.", + uri.GetAuthority().c_str(), bundleName.c_str(), query.key.c_str()); return E_NO_PERMISSION; } } } - if (LifeCycleManager::GetInstance().DeleteOnGet(key) != E_OK) { - ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; - } return E_OK; } @@ -151,7 +200,8 @@ int32_t DataManager::RetrieveBatchData(const QueryOption &query, std::vector &dataSet, std::shared_ptr &store); + int32_t ProcessingUri(const QueryOption &query, UnifiedData &unifiedData); StoreCache storeCache_; std::map authorizationMap_; }; diff --git a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h index c3f45d8d..6f6ef638 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/lifecycle/lifecycle_policy.h @@ -20,8 +20,6 @@ #include "store/store_cache.h" #include "unified_key.h" -#include "error_code.h" -#include "store.h" namespace OHOS { namespace UDMF { 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 130ffa20..10c8ddec 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -12,20 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "PreProcessUtils" #include "preprocess_utils.h" #include -#include "error_code.h" #include "accesstoken_kit.h" #include "bundlemgr/bundle_mgr_client_impl.h" +#include "device_manager_adapter.h" +#include "error_code.h" +#include "file.h" #include "ipc_skeleton.h" - +#include "log_print.h" +#include "remote_file_share.h" +#include "uri.h" namespace OHOS { namespace UDMF { static constexpr int ID_LEN = 32; const char SPECIAL = '^'; +const std::string PERMISSION_PROXY_AUTHORIZATION_URI = "ohos.permission.PROXY_AUTHORIZATION_URI"; +using namespace Security::AccessToken; +using namespace OHOS::AppFileService::ModuleRemoteFileShare; + int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option) { auto it = UD_INTENTION_MAP.find(option.intention); @@ -44,6 +53,8 @@ int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption & runtime.createTime = GetTimeStamp(); runtime.sourcePackage = bundleName; runtime.createPackage = bundleName; + runtime.deviceId = GetLocalDeviceId(); + runtime.recordTotalNum = static_cast(data.GetRecords().size()); data.SetRuntime(runtime); return E_OK; } @@ -71,6 +82,17 @@ time_t PreProcessUtils::GetTimeStamp() return timestamp; } +int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId) +{ + Security::AccessToken::HapTokenInfo tokenInfo; + auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (result != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + ZLOGE("GetHapUidByToken failed, result = %{public}d.", result); + return E_ERROR; + } + return tokenInfo.userID; +} + bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) { Security::AccessToken::HapTokenInfo hapInfo; @@ -92,5 +114,87 @@ bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &proc processName = nativeInfo.processName; return true; } + +std::string PreProcessUtils::GetLocalDeviceId() +{ + auto info = DistributedData::DeviceManagerAdapter::GetInstance().GetLocalDevice(); + std::string encryptedUuid = DistributedData::DeviceManagerAdapter::GetInstance().CalcClientUuid(" ", info.uuid); + return encryptedUuid; +} + +void PreProcessUtils::SetRemoteData(UnifiedData &data) +{ + if (data.IsEmpty()) { + ZLOGD("invalid data."); + return; + } + std::shared_ptr runtime = data.GetRuntime(); + if (runtime->deviceId == GetLocalDeviceId()) { + ZLOGD("not remote data."); + return; + } + ZLOGD("is remote data."); + auto records = data.GetRecords(); + for (auto record : records) { + auto type = record->GetType(); + if (IsFileType(type)) { + auto file = static_cast(record.get()); + UDDetails details = file->GetDetails(); + details.insert({ "isRemote", "true" }); + file->SetDetails(details); + } + } +} + +bool PreProcessUtils::IsFileType(UDType udType) +{ + return (udType == UDType::FILE || udType == UDType::IMAGE || udType == UDType::VIDEO || udType == UDType::AUDIO + || udType == UDType::FOLDER); +} + +int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) +{ + int32_t userId = GetHapUidByToken(tokenId); + std::string bundleName = data.GetRuntime()->createPackage; + for (const auto &record : data.GetRecords()) { + if (record != nullptr && IsFileType(record->GetType())) { + auto file = static_cast(record.get()); + if (file->GetUri().empty()) { + ZLOGW("Get uri empty, plase check the uri."); + continue; + } + Uri uri(file->GetUri()); + if (uri.GetAuthority().empty()) { + ZLOGW("Get uri authority empty."); + continue; + } + if (uri.GetAuthority() != bundleName + && !VerifyCallingPermission(tokenId, PERMISSION_PROXY_AUTHORIZATION_URI)) { + ZLOGE("No auth to handle this uri, authority=%{public}s, bundleName=%{public}s.", + uri.GetAuthority().c_str(), bundleName.c_str()); + return E_NO_PERMISSION; + } + struct HmdfsUriInfo dfsUriInfo; + int ret = RemoteFileShare::GetDfsUriFromLocal(file->GetUri(), userId, dfsUriInfo); + if (ret != 0 || dfsUriInfo.uriStr.empty()) { + ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d.", ret, userId); + return E_FS_ERROR; + } + file->SetRemoteUri(dfsUriInfo.uriStr); + } + } + return E_OK; +} + +bool PreProcessUtils::VerifyCallingPermission(uint32_t tokenId, const std::string &permissionName) +{ + int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName); + if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { + ZLOGE("Permission %{public}s: PERMISSION_DENIED, ret=%{public}d ", permissionName.c_str(), ret); + return false; + } + ZLOGD("Verify AccessToken success, %{public}s", permissionName.c_str()); + 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 175027ea..d9fa54f3 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -30,8 +30,15 @@ public: static int32_t RuntimeDataImputation(UnifiedData &data, CustomOption &option); static std::string IdGenerator(); static time_t GetTimeStamp(); + static int32_t GetHapUidByToken(uint32_t tokenId); static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); + static std::string GetLocalDeviceId(); + static void SetRemoteData(UnifiedData &data); + static bool IsFileType(UDType udType); + static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); +private: + static bool VerifyCallingPermission(uint32_t tokenId, const std::string &permissionName); }; } // namespace UDMF } // namespace OHOS 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 cb957545..25bf609c 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -47,6 +47,16 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) UpdateTime(); std::vector entries; std::string unifiedKey = unifiedData.GetRuntime()->key.GetUnifiedKey(); + // add runtime info + std::vector runtimeBytes; + auto runtimeTlv = TLVObject(runtimeBytes); + if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv)) { + ZLOGE("Marshall runtime info failed, dataPrefix: %{public}s.", unifiedKey.c_str()); + return E_WRITE_PARCEL_ERROR; + } + Entry entry = { Key(unifiedKey), Value(runtimeBytes) }; + entries.push_back(entry); + // add unified record for (const auto &record : unifiedData.GetRecords()) { if (record == nullptr) { @@ -64,15 +74,6 @@ Status RuntimeStore::Put(const UnifiedData &unifiedData) Entry entry = { Key(unifiedKey + "/" + record->GetUid()), Value(recordBytes) }; entries.push_back(entry); } - // add runtime info - std::vector runtimeBytes; - auto runtimeTlv = TLVObject(runtimeBytes); - if (!TLVUtil::Writing(*unifiedData.GetRuntime(), runtimeTlv)) { - ZLOGI("Marshall runtime info failed."); - return E_WRITE_PARCEL_ERROR; - } - Entry entry = { Key(unifiedKey), Value(runtimeBytes) }; - entries.push_back(entry); auto status = PutEntries(entries); return status; } @@ -82,12 +83,12 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) UpdateTime(); std::vector entries; if (GetEntries(key, entries) != E_OK) { - ZLOGI("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); + ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); return E_DB_ERROR; } if (entries.empty()) { - ZLOGD("entries is empty."); - return E_OK; + ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); + return E_NOT_FOUND; } return UnMarshalEntries(key, entries, unifiedData); } @@ -97,7 +98,7 @@ Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) UpdateTime(); UnifiedData unifiedData; if (Get(key, unifiedData) != E_OK) { - ZLOGE("Get unified data failed."); + ZLOGE("Get unified data failed, dataPrefix: %{public}s", key.c_str()); return E_DB_ERROR; } @@ -295,9 +296,7 @@ Status RuntimeStore::UnMarshalEntries(const std::string &key, std::vector return E_READ_PARCEL_ERROR; } unifiedData.SetRuntime(runtime); - break; - } - if (keyStr.find(key) == 0) { + } else if (keyStr.find(key) == 0) { std::shared_ptr record; auto recordTlv = TLVObject(const_cast &>(entry.value.Data())); if (!TLVUtil::Reading(record, recordTlv)) { 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 dcbf8b47..b343283b 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -22,10 +22,13 @@ #include "lifecycle/lifecycle_manager.h" #include "log_print.h" #include "preprocess_utils.h" +#include "reporter.h" namespace OHOS { namespace UDMF { using FeatureSystem = DistributedData::FeatureSystem; +using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; +using Reporter = OHOS::DistributedDataDfx::Reporter; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -46,13 +49,49 @@ UdmfServiceImpl::Factory::~Factory() int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { ZLOGD("start"); - return DataManager::GetInstance().SaveData(option, unifiedData, key); + int32_t res = E_OK; + UdmfBehaviourMsg msg; + auto find = UD_INTENTION_MAP.find(option.intention); + msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; + msg.operation = "insert"; + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) { + msg.appId = "unknown"; + res = E_ERROR; + } else { + msg.appId = bundleName; + res = DataManager::GetInstance().SaveData(option, unifiedData, key); + } + auto errFind = ERROR_MAP.find(res); + msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; + msg.dataType = unifiedData.GetTypes(); + msg.dataSize = unifiedData.GetSize(); + Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); + return res; } int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData) { ZLOGD("start"); - return DataManager::GetInstance().RetrieveData(query, unifiedData); + int32_t res = E_OK; + UdmfBehaviourMsg msg; + auto find = UD_INTENTION_MAP.find(query.intention); + msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second; + msg.operation = "insert"; + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { + msg.appId = "unknown"; + res = E_ERROR; + } else { + msg.appId = bundleName; + res = DataManager::GetInstance().RetrieveData(query, unifiedData); + } + auto errFind = ERROR_MAP.find(res); + msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second; + msg.dataType = unifiedData.GetTypes(); + msg.dataSize = unifiedData.GetSize(); + Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg); + return res; } int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) diff --git a/kv_store/CODEOWNERS b/kv_store/CODEOWNERS new file mode 100644 index 00000000..91b62a26 --- /dev/null +++ b/kv_store/CODEOWNERS @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# any change to +# frameworks/innerkitsimpl/distributeddatafwk/include/distributeddata_ipc_interface_code.h +# frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h +# needs to be reviewed by @leonchan5 +frameworks/innerkitsimpl/distributeddatafwk/include/distributeddata_ipc_interface_code.h @leonchan5 +frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h @leonchan5 \ No newline at end of file diff --git a/kv_store/bundle.json b/kv_store/bundle.json index 63a0761f..be74bfc0 100644 --- a/kv_store/bundle.json +++ b/kv_store/bundle.json @@ -103,6 +103,76 @@ ], "header_base": "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include" } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", + "header": { + "header_files": [ + "get_query_info.h", + "intercepted_data.h", + "iprocess_communicator.h", + "iprocess_system_api_adapter.h", + "ithread_pool.h", + "kv_store_changed_data.h", + "kv_store_delegate.h", + "kv_store_delegate_manager.h", + "kv_store_errno.h", + "kv_store_nb_conflict_data.h", + "kv_store_nb_delegate.h", + "kv_store_observer.h", + "kv_store_result_set.h", + "kv_store_snapshot_delegate.h", + "runtime_config.h", + "store_changed_data.h", + "store_observer.h", + "store_types.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include" + } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", + "header": { + "header_files": [ + "cloud_store_types.h", + "iAssetLoader.h", + "icloud_data_translate.h", + "icloud_db.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/cloud" + } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", + "header": { + "header_files": [ + "relational_store_delegate.h", + "relational_store_manager.h", + "relational_store_sqlite_ext.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/relational" + } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", + "header": { + "header_files": [ + "auto_launch_export.h", + "query.h", + "query_expression.h", + "types_export.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include" + } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", + "header": { + "header_files": [ + "result_set.h" + ], + "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include/distributeddb" + } } ], "test": [ diff --git a/kv_store/frameworks/common/executor_pool.h b/kv_store/frameworks/common/executor_pool.h index 9a0887ac..309e562f 100644 --- a/kv_store/frameworks/common/executor_pool.h +++ b/kv_store/frameworks/common/executor_pool.h @@ -41,23 +41,21 @@ public: static constexpr TaskId INVALID_TASK_ID = static_cast(0l); ExecutorPool(size_t max, size_t min) + : pool_(max, min), delayTasks_(InnerTask(), NextTimer), taskId_(INVALID_TASK_ID) { - pool_ = new (std::nothrow) Pool(max, min); - execs_ = new (std::nothrow) TaskQueue(InnerTask()); - delayTasks_ = new (std::nothrow) TaskQueue(InnerTask(), [](InnerTask &task) -> std::pair { - if (task.interval != INVALID_INTERVAL && --task.times > 0) { - auto time = std::chrono::steady_clock::now() + task.interval; - return { true, time }; - } - return { false, INVALID_TIME }; - }); - taskId_ = INVALID_TASK_ID; + // When max equals 1, timer thread schedules and executes tasks. + if (max > 1) { + execs_ = new (std::nothrow) TaskQueue(InnerTask()); + } } + ~ExecutorPool() { poolStatus = Status::IS_STOPPING; - execs_->Clean(); - delayTasks_->Clean(); + if (execs_ != nullptr) { + execs_->Clean(); + } + delayTasks_.Clean(); std::shared_ptr scheduler; { std::lock_guard scheduleLock(mtx_); @@ -66,12 +64,10 @@ public: if (scheduler != nullptr) { scheduler->Stop(true); } - pool_->Clean([](std::shared_ptr executor) { + pool_.Clean([](std::shared_ptr executor) { executor->Stop(true); }); delete execs_; - delete delayTasks_; - delete pool_; poolStatus = Status::STOPPED; } @@ -80,6 +76,11 @@ public: if (poolStatus != Status::RUNNING) { return INVALID_TASK_ID; } + + if (execs_ == nullptr) { + return Schedule(std::move(task), INVALID_DELAY, INVALID_INTERVAL, UNLIMITED_TIMES); + } + return Execute(std::move(task), GenTaskId()); } @@ -111,18 +112,20 @@ public: bool Remove(TaskId taskId, bool wait = false) { bool res = true; - auto delay = delayTasks_->Find(taskId); + auto delay = delayTasks_.Find(taskId); if (!delay.Valid()) { res = false; } - delayTasks_->Remove(taskId, wait); - execs_->Remove(taskId, wait); + delayTasks_.Remove(taskId, wait); + if (execs_ != nullptr) { + execs_->Remove(taskId, wait); + } return res; } TaskId Reset(TaskId taskId, Duration interval) { - auto updated = delayTasks_->Update(taskId, [interval](InnerTask &task) -> std::pair { + auto updated = delayTasks_.Update(taskId, [interval](InnerTask &task) -> std::pair { if (task.interval != INVALID_INTERVAL) { task.interval = interval; } @@ -139,47 +142,49 @@ private: innerTask.exec = task; innerTask.taskId = taskId; execs_->Push(std::move(innerTask), taskId, INVALID_TIME); - auto executor = pool_->Get(); + auto executor = pool_.Get(); if (executor == nullptr) { return taskId; } executor->Bind( execs_, [this](std::shared_ptr exe) { - pool_->Idle(exe); + pool_.Idle(exe); return true; }, [this](std::shared_ptr exe, bool force) -> bool { - return pool_->Release(exe, force); + return pool_.Release(exe, force); }); return taskId; } TaskId Schedule(InnerTask innerTask, Time delay) { - auto func = innerTask.exec; auto id = innerTask.taskId; - auto run = [this, func, id]() { - Execute(func, id); - }; - innerTask.exec = run; - delayTasks_->Push(std::move(innerTask), id, delay); + if (execs_ != nullptr) { + auto func = innerTask.exec; + auto run = [this, func, id]() { + Execute(func, id); + }; + innerTask.exec = run; + } + delayTasks_.Push(std::move(innerTask), id, delay); std::lock_guard scheduleLock(mtx_); if (scheduler_ == nullptr) { - scheduler_ = pool_->Get(true); + scheduler_ = pool_.Get(true); scheduler_->Bind( - delayTasks_, + &delayTasks_, [this](std::shared_ptr exe) { std::unique_lock lock(mtx_); - if (delayTasks_->Size() != 0) { + if (delayTasks_.Size() != 0) { return false; } scheduler_ = nullptr; - pool_->Idle(exe); + pool_.Idle(exe); return true; }, [this](std::shared_ptr exe, bool force) -> bool { - return pool_->Release(exe, force); + return pool_.Release(exe, force); }); } return innerTask.taskId; @@ -194,12 +199,21 @@ private: return taskId; } + static std::pair NextTimer(InnerTask &task) + { + if (task.interval != INVALID_INTERVAL && --task.times > 0) { + auto time = std::chrono::steady_clock::now() + task.interval; + return { true, time }; + } + return { false, INVALID_TIME }; + } + Status poolStatus = Status::RUNNING; std::mutex mtx_; - Pool *pool_; + Pool pool_; + TaskQueue delayTasks_; std::shared_ptr scheduler_ = nullptr; - TaskQueue *execs_; - TaskQueue *delayTasks_; + TaskQueue *execs_ = nullptr; std::atomic taskId_; }; } // namespace OHOS diff --git a/kv_store/frameworks/common/log_print.h b/kv_store/frameworks/common/log_print.h index 67fbf5ce..dbbe8e82 100644 --- a/kv_store/frameworks/common/log_print.h +++ b/kv_store/frameworks/common/log_print.h @@ -129,4 +129,4 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() #error // unknown system #endif -#endif // DISTRIBUTEDDATA_LOG_PRINT_H +#endif // DISTRIBUTEDDATA_LOG_PRINT_H \ No newline at end of file diff --git a/kv_store/frameworks/common/test/executor_pool_test.cpp b/kv_store/frameworks/common/test/executor_pool_test.cpp index 66eccd34..aca8d486 100644 --- a/kv_store/frameworks/common/test/executor_pool_test.cpp +++ b/kv_store/frameworks/common/test/executor_pool_test.cpp @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "executor_pool.h" + #include #include "block_data.h" -#include "executor_pool.h" namespace OHOS::Test { using namespace testing::ext; @@ -114,10 +115,8 @@ HWTEST_F(ExecutorPoolTest, MultiSchedule, TestSize.Level0) } std::this_thread::sleep_for(std::chrono::milliseconds(LONG_INTERVAL * 10)); ASSERT_EQ(data->data, 100); - auto it = ids.begin(); - while (it != ids.end()) { - executorPool_->Remove(*it); - it++; + for (auto id : ids) { + executorPool_->Remove(id); } } /** @@ -163,5 +162,30 @@ HWTEST_F(ExecutorPoolTest, Reset, TestSize.Level0) ASSERT_EQ(data->data, 3); executorPool_->Remove(temp); } -//auto blockData = std::make_shared>(LONG_INTERVAL, testData); + +/** +* @tc.name: MaxEqualsOne +* @tc.desc: +* @tc.type: FUNC +* @tc.require: +* @tc.author: CRJ +*/ +HWTEST_F(ExecutorPoolTest, MaxEqualsOne, TestSize.Level0) +{ + auto executors = std::make_shared(1, 0); + std::atomic testNum = 1; + auto delayTask = [&testNum] { + testNum++; + }; + auto task = [&testNum] { + testNum += 2; + }; + executors->Schedule(std::chrono::milliseconds(SHORT_INTERVAL * 2), delayTask); + ASSERT_EQ(testNum, 1); + executors->Execute(task); + std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL)); + ASSERT_EQ(testNum, 3); + std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL * 2)); + ASSERT_EQ(testNum, 4); +} } // namespace OHOS::Test diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index 394b27a4..fda4ce86 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -40,9 +40,6 @@ StoreFactory::StoreFactory() convertors_[SINGLE_VERSION] = new Convertor(); convertors_[MULTI_VERSION] = new Convertor(); DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared()); - DistributedDB::RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam ¶m) -> bool { - return false; - }); if (DBManager::IsProcessSystemApiAdapterValid()) { return; } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp index 0e53902f..63983305 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp @@ -328,8 +328,6 @@ HWTEST_F(AutoSyncTimerTest, MultiWriteOvertenKVStores, TestSize.Level1) EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); ASSERT_GE(instance->endTime - instance->startTime, 200); ASSERT_LT(instance->endTime - instance->startTime, 250); - finished.store(true); - thread.join(); EXPECT_EQ(static_cast(instance->GetCallCount(11)), 11); auto it = instance->values_.find("ut_test"); ASSERT_EQ(it->second.count("ut_test_store0"), 1); @@ -343,6 +341,8 @@ HWTEST_F(AutoSyncTimerTest, MultiWriteOvertenKVStores, TestSize.Level1) ASSERT_EQ(it->second.count("ut_test_store8"), 1); ASSERT_EQ(it->second.count("ut_test_store9"), 1); ASSERT_EQ(it->second.count("ut_test_store10"), 1); + finished.store(true); + thread.join(); } /** diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp index 9cd6bc9c..5a0017b6 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp @@ -1157,6 +1157,7 @@ struct SyncContext : public ContextBase { this->status = JSUtil::GetValue(env, argv[3], this->allowedDelayMs); ASSERT_BUSINESS_ERR(this, (this->status == napi_ok || JSUtil::IsNull(env, argv[3])), Status::INVALID_ARGUMENT, "The parameters delay is incorrect."); + this->status = napi_ok; } } if (this->type == napi_number) { @@ -1167,6 +1168,7 @@ struct SyncContext : public ContextBase { this->status = JSUtil::GetValue(env, argv[2], this->allowedDelayMs); ASSERT_BUSINESS_ERR(this, (this->status == napi_ok || JSUtil::IsNull(env, argv[2])), Status::INVALID_ARGUMENT, "The parameters delay is incorrect."); + this->status = napi_ok; } } ASSERT_BUSINESS_ERR(this, (this->mode <= uint32_t(SyncMode::PUSH_PULL)) && (this->status == napi_ok), diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp index b201ea9e..6c00358c 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp @@ -1273,7 +1273,7 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, ContextParam &pa napi_value hapInfo = nullptr; GetNamedProperty(env, in, "currentHapModuleInfo", hapInfo); if (hapInfo != nullptr) { - statusMsg = GetNamedProperty(env, hapInfo, "moduleName", param.hapName); + statusMsg = GetNamedProperty(env, hapInfo, "name", param.hapName); ASSERT(statusMsg.status == napi_ok, "get hap name failed", napi_invalid_arg); } napi_value appInfo = nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h index 8a34bde8..2ff010a3 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_errno.h @@ -134,6 +134,8 @@ constexpr int E_CLOUD_NETWORK_ERROR = (E_BASE + 113); // network error in cloud constexpr int E_CLOUD_SYNC_UNSET = (E_BASE + 114); // not set sync option in cloud constexpr int E_CLOUD_FULL_RECORDS = (E_BASE + 115); // cloud's record is full constexpr int E_CLOUD_LOCK_ERROR = (E_BASE + 116); // cloud failed to get sync lock +constexpr int E_CLOUD_ASSET_SPACE_INSUFFICIENT = (E_BASE + 117); // cloud failed to download asset +constexpr int E_CLOUD_INVALID_ASSET = (E_BASE + 118); // the asset is invalid // Num 150+ is reserved for schema related errno, since it may be added regularly constexpr int E_JSON_PARSE_FAIL = (E_BASE + 150); // Parse json fail in grammatical level constexpr int E_JSON_INSERT_PATH_EXIST = (E_BASE + 151); // Path already exist before insert diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h index d11ce741..02706faa 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_types.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_types.h @@ -123,6 +123,7 @@ enum class OperatePerm { REKEY_MONOPOLIZE_PERM, IMPORT_MONOPOLIZE_PERM, DISABLE_PERM, + RESTART_SYNC_PERM, }; enum SingleVerConflictResolvePolicy { diff --git a/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h b/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h index 139fd701..7c469e00 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/relational/table_info.h @@ -51,6 +51,9 @@ public: std::string ToAttributeString() const; int CompareWithField(const FieldInfo &inField, bool isLite = false) const; + + bool IsAssetType() const; + bool IsAssetsType() const; private: std::string fieldName_; std::string dataType_; // Type may be null diff --git a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp index e9bb95a6..2af29a0d 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp @@ -1247,6 +1247,9 @@ int AutoLaunch::RegisterKvObserver(AutoLaunchItem &autoLaunchItem, const std::st int AutoLaunch::RegisterRelationalObserver(AutoLaunchItem &autoLaunchItem, const std::string &identifier, bool isExt) { + if (autoLaunchItem.storeObserver == nullptr) { + return E_OK; + } RelationalStoreConnection *conn = static_cast(autoLaunchItem.conn); conn->RegisterObserverAction([this, autoLaunchItem, identifier](const std::string &changedDevice, ChangedData &&changedData, bool isChangedData) { diff --git a/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp b/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp index d6ce49c1..eec56911 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/relational/table_info.cpp @@ -67,11 +67,6 @@ enum AffinityPattern : uint32_t { }; } -bool IsAssetType(const std::string &dataType) -{ - return (strcasecmp(dataType.c_str(), ASSET) == 0 || strcasecmp(dataType.c_str(), ASSETS) == 0); -} - static StorageType AffinityType(const std::string &dataType) { StorageType type = StorageType::STORAGE_TYPE_NULL; @@ -104,7 +99,7 @@ void FieldInfo::SetDataType(const std::string &dataType) { dataType_ = dataType; std::transform(dataType_.begin(), dataType_.end(), dataType_.begin(), ::tolower); - if (IsAssetType(dataType_)) { + if (IsAssetType() || IsAssetsType()) { storageType_ = StorageType::STORAGE_TYPE_BLOB; // use for cloud sync } else { storageType_ = AffinityType(dataType_); @@ -193,6 +188,16 @@ int FieldInfo::CompareWithField(const FieldInfo &inField, bool isLite) const return hasDefaultValue_ == inField.HasDefaultValue(); } +bool FieldInfo::IsAssetType() const +{ + return strcasecmp(dataType_.c_str(), ASSET) == 0; +} + +bool FieldInfo::IsAssetsType() const +{ + return strcasecmp(dataType_.c_str(), ASSETS) == 0; +} + const std::string &TableInfo::GetTableName() const { return tableName_; diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp index 8c249fd7..6c9acf42 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -297,6 +297,7 @@ NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const } LOGD("[RuntimeContext] TimeTickMonitor start success"); } + LOGD("[RuntimeContext] call RegisterTimeChangedLister"); return timeTickMonitor_->RegisterTimeChangedLister(action, finalize, errCode); } @@ -756,6 +757,7 @@ void RuntimeContextImpl::StopTimeTickMonitorIfNeed() LOGD("[RuntimeContext] TimeTickMonitor exist because no listener"); timeTickMonitor_ = nullptr; } + LOGD("[RuntimeContext] TimeTickMonitor can not stop because listener is not empty"); } void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback) diff --git a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp index 1c8756f4..24912e3a 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp @@ -32,6 +32,7 @@ TimeTickMonitor::TimeTickMonitor() TimeTickMonitor::~TimeTickMonitor() { + LOGD("TimeTickMonitor destroy"); StopTimeTickMonitor(); runtimeCxt_ = nullptr; } diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h index cf1dac93..6a641864 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_aggregator.h @@ -95,7 +95,7 @@ private: // Working in a dedicated thread void SendDataRoutine(); void SendPacketsAndDisposeTask(const SendTask &inTask, uint32_t mtu, - const std::vector>> &eachPacket); + const std::vector>> &eachPacket, uint32_t totalLength); int RetryUntilTimeout(SendTask &inTask, uint32_t timeout, Priority inPrio); void TaskFinalizer(const SendTask &inTask, int result); diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h b/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h index d68916fa..9945c8d4 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h @@ -54,7 +54,8 @@ public: // Not assume bytes to be heap memory. Not assume SendBytes to be not blocking // Return 0 as success. Return negative as error - virtual int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length) = 0; + virtual int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length, + uint32_t totalLength) = 0; // Pass nullptr as inHandle to do unReg if need (inDecRef also nullptr) // Return 0 as success. Return negative as error @@ -76,4 +77,4 @@ public: }; } // namespace DistributedDB -#endif // IADAPTER_H +#endif // IADAPTER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/network_adapter.h b/kv_store/frameworks/libs/distributeddb/communicator/include/network_adapter.h index 580e48c0..6be4e1e4 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/network_adapter.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/network_adapter.h @@ -44,7 +44,8 @@ public: uint32_t GetTimeout(const std::string &target) override; int GetLocalIdentity(std::string &outTarget) override; - int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length) override; + int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length, + uint32_t totalLength) override; int RegBytesReceiveCallback(const BytesReceiveCallback &onReceive, const Finalizer &inOper) override; int RegTargetChangeCallback(const TargetChangeCallback &onChange, const Finalizer &inOper) override; @@ -92,4 +93,4 @@ private: }; } // namespace DistributedDB -#endif +#endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h index 9821a640..0d502030 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h @@ -63,8 +63,8 @@ public: int AddSendTaskIntoSchedule(const SendTask &inTask, Priority inPrio); // This method for consumer, not recommend for multiple thread - int ScheduleOutSendTask(SendTask &outTask); - int ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outTaskInfo); + int ScheduleOutSendTask(SendTask &outTask, uint32_t &totalLength); + int ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outTaskInfo, uint32_t &totalLength); // This method for consumer, call ScheduleOutSendTask at least one time before each calling this int FinalizeLastScheduleTask(); @@ -88,6 +88,7 @@ private: std::vector priorityOrder_; std::map extraCapacityInByteByPrio_; std::map policyMap_; + std::map totalBytesByTarget_; std::map taskCountByPrio_; std::map taskDelayCountByPrio_; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp index 0fe52b83..c1579be1 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -358,7 +358,7 @@ void CommunicatorAggregator::SendDataRoutine() } void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, uint32_t mtu, - const std::vector>> &eachPacket) + const std::vector>> &eachPacket, uint32_t totalLength) { bool taskNeedFinalize = true; int errCode = E_OK; @@ -373,7 +373,7 @@ void CommunicatorAggregator::SendPacketsAndDisposeTask(const SendTask &inTask, u LOGI("[CommAggr][SendPackets] DoSendBytes, dstTarget=%s{private}, extendHeadLength=%" PRIu32 ", totalLength=%" PRIu32 ".", inTask.dstTarget.c_str(), entry.second.first, entry.second.second); ProtocolProto::DisplayPacketInformation(entry.first + entry.second.first, entry.second.second); - errCode = adapterHandle_->SendBytes(inTask.dstTarget, entry.first, entry.second.second); + errCode = adapterHandle_->SendBytes(inTask.dstTarget, entry.first, entry.second.second, totalLength); { std::lock_guard autoLock(sendRecordMutex_); sendRecord_[inTask.frameId].sendIndex = index; @@ -886,7 +886,8 @@ void CommunicatorAggregator::InitSendThread() void CommunicatorAggregator::SendOnceData() { SendTask taskToSend; - int errCode = scheduler_.ScheduleOutSendTask(taskToSend); + uint32_t totalLength = 0; + int errCode = scheduler_.ScheduleOutSendTask(taskToSend, totalLength); if (errCode != E_OK) { return; // Not possible to happen } @@ -917,7 +918,7 @@ void CommunicatorAggregator::SendOnceData() } } - SendPacketsAndDisposeTask(taskToSend, mtu, eachPacket); + SendPacketsAndDisposeTask(taskToSend, mtu, eachPacket, totalLength); } void CommunicatorAggregator::TriggerSendData() diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp index 0422edd9..2b9822b6 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp @@ -205,7 +205,7 @@ int NetworkAdapter::GetLocalIdentity(std::string &outTarget) return E_OK; } -int NetworkAdapter::SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length) +int NetworkAdapter::SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length, uint32_t totalLength) { if (bytes == nullptr || length == 0) { return -E_INVALID_ARGS; @@ -213,7 +213,7 @@ int NetworkAdapter::SendBytes(const std::string &dstTarget, const uint8_t *bytes LOGI("[NAdapt][SendBytes] Enter, to=%s{private}, length=%u", dstTarget.c_str(), length); DeviceInfos dstDevInfo; dstDevInfo.identifier = dstTarget; - DBStatus errCode = processCommunicator_->SendData(dstDevInfo, bytes, length); + DBStatus errCode = processCommunicator_->SendData(dstDevInfo, bytes, length, totalLength); if (errCode == DBStatus::RATE_LIMIT) { LOGD("[NAdapt][SendBytes] rate limit!"); return -E_WAIT_RETRY; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp index 23c4e079..bf36a532 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp @@ -52,7 +52,8 @@ void SendTaskScheduler::Finalize() while (GetTotalTaskCount() != 0) { SendTask task; SendTaskInfo taskInfo; - int errCode = ScheduleOutSendTask(task, taskInfo); + uint32_t totalLength = 0; + int errCode = ScheduleOutSendTask(task, taskInfo, totalLength); if (errCode != E_OK) { LOGE("[Scheduler][Final] INTERNAL ERROR."); break; // Not possible to happen @@ -73,6 +74,7 @@ int SendTaskScheduler::AddSendTaskIntoSchedule(const SendTask &inTask, Priority uint32_t taskSizeByByte = inTask.buffer->GetSize(); curTotalSizeByByte_ += taskSizeByByte; curTotalSizeByTask_++; + totalBytesByTarget_[inTask.dstTarget] += taskSizeByByte; if (policyMap_.count(inTask.dstTarget) == 0) { policyMap_[inTask.dstTarget] = TargetPolicy::NO_DELAY; } @@ -87,10 +89,10 @@ int SendTaskScheduler::AddSendTaskIntoSchedule(const SendTask &inTask, Priority return E_OK; } -int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask) +int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask, uint32_t &totalLength) { SendTaskInfo taskInfo; - int errCode = ScheduleOutSendTask(outTask, taskInfo); + int errCode = ScheduleOutSendTask(outTask, taskInfo, totalLength); if (errCode == E_OK) { LOGI("[Scheduler][OutTask] dstTarget=%s{private}, delayFlag=%d, taskPrio=%d", outTask.dstTarget.c_str(), taskInfo.delayFlag, static_cast(taskInfo.taskPrio)); @@ -98,7 +100,7 @@ int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask) return errCode; } -int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outTaskInfo) +int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outTaskInfo, uint32_t &totalLength) { std::lock_guard overallLockGuard(overallMutex_); if (curTotalSizeByTask_ == 0) { @@ -110,6 +112,7 @@ int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outT int errCode = ScheduleDelayTask(outTask, outTaskInfo); if (errCode == E_OK) { // Update last schedule location + totalLength = totalBytesByTarget_[outTask.dstTarget]; lastScheduleTarget_ = outTask.dstTarget; lastSchedulePriority_ = outTaskInfo.taskPrio; scheduledFlag_ = true; @@ -120,6 +123,7 @@ int SendTaskScheduler::ScheduleOutSendTask(SendTask &outTask, SendTaskInfo &outT int errCode = ScheduleNoDelayTask(outTask, outTaskInfo); if (errCode == E_OK) { // Update last schedule location + totalLength = totalBytesByTarget_[outTask.dstTarget]; lastScheduleTarget_ = outTask.dstTarget; lastSchedulePriority_ = outTaskInfo.taskPrio; scheduledFlag_ = true; @@ -146,6 +150,8 @@ int SendTaskScheduler::FinalizeLastScheduleTask() curTotalSizeByByte_ -= taskSize; bool isFullAfter = (curTotalSizeByByte_ >= MAX_CAPACITY); + totalBytesByTarget_[lastScheduleTarget_] -= taskSize; + curTotalSizeByTask_--; taskCountByPrio_[lastSchedulePriority_]--; if (policyMap_[lastScheduleTarget_] == TargetPolicy::DELAY) { @@ -282,4 +288,4 @@ int SendTaskScheduler::ScheduleNoDelayTask(SendTask &outTask, SendTaskInfo &outT LOGE("[Scheduler][ScheduleNoDelay] INTERNAL ERROR : NO TASK."); return -E_INTERNAL_ERROR; } -} +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/distributeddb.gni b/kv_store/frameworks/libs/distributeddb/distributeddb.gni index 686ac7b2..eb9ef3d5 100644 --- a/kv_store/frameworks/libs/distributeddb/distributeddb.gni +++ b/kv_store/frameworks/libs/distributeddb/distributeddb.gni @@ -185,6 +185,7 @@ distributeddb_src = [ "${distributeddb_path}/syncer/src/cloud/cloud_merge_strategy.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_db_proxy.cpp", "${distributeddb_path}/syncer/src/cloud/cloud_syncer.cpp", + "${distributeddb_path}/syncer/src/cloud/cloud_sync_utils.cpp", "${distributeddb_path}/syncer/src/cloud/strategy_factory.cpp", "${distributeddb_path}/syncer/src/commit_history_sync.cpp", "${distributeddb_path}/syncer/src/communicator_proxy.cpp", diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h index e500a78f..1677f44a 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h @@ -94,6 +94,12 @@ public: // Only the identifier field of dstDevInfo must be valid, no requirement for other field. virtual DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) = 0; + virtual DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, uint32_t totalLength) + { + (void)totalLength; + return SendData(dstDevInfo, data, length); + } + // The GetMtuSize function can be called anytime regardless of whether started or stopped. // The mtuSize should not less than 1K otherwise it will be regard as 1K. // For run on OHOS, there is agreement that the mtuSize should be nearly 5M. diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h index 967ea470..b0981f22 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h @@ -50,6 +50,8 @@ public: DB_API virtual DBStatus Sync(const std::vector &devices, SyncMode mode, const Query &query, const SyncStatusCallback &onComplete, bool wait) = 0; + DB_API virtual int32_t GetCloudSyncTaskCount() = 0; + DB_API DBStatus RemoveDeviceData(const std::string &device, ClearMode mode = DEFAULT) { return RemoveDeviceDataInner(device, mode); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h index 6ab481aa..0e7b9e29 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -76,6 +76,7 @@ enum DBStatus { CLOUD_SYNC_UNSET, // not set sync option in cloud CLOUD_FULL_RECORDS, // cloud's record is full CLOUD_LOCK_ERROR, // cloud failed to get sync lock + CLOUD_ASSET_SPACE_INSUFFICIENT, // cloud failed to download asset }; struct KvStoreConfig { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp index cb217cad..0c5c4b61 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp @@ -74,6 +74,7 @@ namespace { { -E_CLOUD_SYNC_UNSET, CLOUD_SYNC_UNSET }, { -E_CLOUD_FULL_RECORDS, CLOUD_FULL_RECORDS }, { -E_CLOUD_LOCK_ERROR, CLOUD_LOCK_ERROR }, + { -E_CLOUD_ASSET_SPACE_INSUFFICIENT, CLOUD_ASSET_SPACE_INSUFFICIENT }, }; } diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index f7bac8f5..21a773a8 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -39,17 +39,17 @@ RelationalStoreDelegateImpl::~RelationalStoreDelegateImpl() } conn_ = nullptr; -}; +} DBStatus RelationalStoreDelegateImpl::RemoveDeviceDataInner(const std::string &device, ClearMode mode) { - if (mode >= BUTT) { + if (mode >= BUTT || mode < 0) { LOGE("Invalid mode for Remove device data, %d.", INVALID_ARGS); return INVALID_ARGS; } if (mode == FLAG_ONLY || mode == FLAG_AND_DATA) { if (conn_ == nullptr) { - LOGE("Invalid connection for operation!"); + LOGE("[RelationalStore Delegate] Invalid connection for operation!"); return DB_ERROR; } @@ -63,6 +63,19 @@ DBStatus RelationalStoreDelegateImpl::RemoveDeviceDataInner(const std::string &d return RemoveDeviceData(device, ""); } +int32_t RelationalStoreDelegateImpl::GetCloudSyncTaskCount() +{ + if (conn_ == nullptr) { + LOGE("[RelationalStore Delegate] Invalid connection for operation!"); + return -1; + } + int32_t count = conn_->GetCloudSyncTaskCount(); + if (count == -1) { + LOGE("[RelationalStore Delegate] Failed to get cloud sync task count."); + } + return count; +} + DBStatus RelationalStoreDelegateImpl::CreateDistributedTableInner(const std::string &tableName, TableSyncType type) { if (!ParamCheckUtils::CheckRelationalTableName(tableName)) { @@ -230,10 +243,7 @@ DBStatus RelationalStoreDelegateImpl::SetCloudDB(const std::shared_ptr DBStatus RelationalStoreDelegateImpl::SetCloudDbSchema(const DataBaseSchema &schema) { - if (conn_ == nullptr) { - return DB_ERROR; - } - if (conn_->SetCloudDbSchema(schema) != E_OK) { + if (conn_ == nullptr || conn_->SetCloudDbSchema(schema) != E_OK) { return DB_ERROR; } return OK; @@ -270,10 +280,7 @@ DBStatus RelationalStoreDelegateImpl::RegisterObserver(StoreObserver *observer) DBStatus RelationalStoreDelegateImpl::SetIAssetLoader(const std::shared_ptr &loader) { - if (conn_ == nullptr) { - return DB_ERROR; - } - if (conn_->SetIAssetLoader(loader) != E_OK) { + if (conn_ == nullptr || conn_->SetIAssetLoader(loader) != E_OK) { return DB_ERROR; } return OK; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h index 2bec6363..bcd3de63 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h @@ -32,6 +32,8 @@ public: DBStatus Sync(const std::vector &devices, SyncMode mode, const Query &query, const SyncStatusCallback &onComplete, bool wait) override; + int32_t GetCloudSyncTaskCount() override; + DBStatus RemoveDeviceDataInner(const std::string &device, ClearMode mode) override; DBStatus DoClean(ClearMode mode); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index 7f27c6ba..584735a5 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -113,7 +113,7 @@ DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const conn->Close(); return DB_ERROR; } - return delegate->RegisterObserver(option.observer); + return option.observer != nullptr ? delegate->RegisterObserver(option.observer) : OK; } DBStatus RelationalStoreManager::CloseStore(RelationalStoreDelegate *store) @@ -157,7 +157,7 @@ DB_API std::vector RelationalStoreManager::CalcPrimaryKeyHash(const std int errCode = E_OK; if (primaryKey.size() == 1) { auto iter = primaryKey.begin(); - Field field = { iter->first, static_cast(iter->second.index()), true, false}; + Field field = {iter->first, static_cast(iter->second.index()), true, false}; errCode = CloudStorageUtils::CalculateHashKeyForOneField(field, primaryKey, false, result); if (errCode != E_OK) { // never happen @@ -166,9 +166,9 @@ DB_API std::vector RelationalStoreManager::CalcPrimaryKeyHash(const std } } else { std::vector tempRes; - for (const auto &item: primaryKey) { + for (const auto &item : primaryKey) { std::vector temp; - Field field = { item.first, static_cast(item.second.index()), true, false}; + Field field = {item.first, static_cast(item.second.index()), true, false}; errCode = CloudStorageUtils::CalculateHashKeyForOneField(field, primaryKey, false, temp); if (errCode != E_OK) { // never happen diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h index b6ce9ac8..10502737 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h @@ -102,7 +102,7 @@ public: const std::string &targetID) const override; int CheckAndInitQueryCondition(QueryObject &query) const override; - void RegisterObserverAction(const RelationalObserverAction &action); + void RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action); void TriggerObserverAction(const std::string &deviceName, ChangedData &&changedData, bool isChangedData) override; int CreateDistributedDeviceTable(const std::string &device, const RelationalSyncStrategy &syncStrategy) override; @@ -158,7 +158,7 @@ public: int PutCloudSyncData(const std::string &tableName, DownloadData &downloadData) override; int CleanCloudData(ClearMode mode, const std::vector &tableNameList, - std::vector &assets) override; + const RelationalSchemaObject &localSchema, std::vector &assets) override; int FillCloudAssetForDownload(const std::string &tableName, VBucket &asset, bool isFullReplace) override; @@ -166,6 +166,10 @@ public: void SetSyncAbleEngine(std::shared_ptr syncAbleEngine); + std::string GetIdentify() const override; + + void EraseDataChangeCallback(uint64_t connectionId); + private: SQLiteSingleVerRelationalStorageExecutor *GetHandle(bool isWrite, int &errCode, OperatePerm perm = OperatePerm::NORMAL_PERM) const; @@ -188,7 +192,7 @@ private: std::function onSchemaChanged_; mutable std::mutex onSchemaChangedMutex_; std::mutex dataChangeDeviceMutex_; - RelationalObserverAction dataChangeDeviceCallback_; + std::map dataChangeCallbackMap_; std::function heartBeatListener_; mutable std::mutex heartBeatMutex_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h index 539a139b..bc8cf3c4 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h @@ -45,16 +45,20 @@ public: static std::map GetCloudPrimaryKeyFieldMap(const TableSchema &tableSchema); static bool IsContainsPrimaryKey(const TableSchema &tableSchema); static std::vector GetCloudAsset(const TableSchema &tableSchema); - static int CheckAssetFromSchema(const TableSchema &tableSchema, VBucket &vBucket, + static int GetAssetFieldsFromSchema(const TableSchema &tableSchema, VBucket &vBucket, std::vector &fields); static void ObtainAssetFromVBucket(const VBucket &vBucket, VBucket &asset); static AssetOpType StatusToFlag(AssetStatus status); static AssetStatus FlagToStatus(AssetOpType opType); - static int FillAssetForDownload(Asset &asset); - static void FillAssetsForDownload(Assets &assets); + static void ChangeAssetsOnVBucketToAsset(VBucket &vBucket, std::vector &fields); + static Type GetAssetFromAssets(Type &value); + static void FillAssetBeforeDownload(Asset &asset); + static void FillAssetAfterDownloadFail(Asset &asset); + static int FillAssetAfterDownload(Asset &asset); + static void FillAssetsAfterDownload(Assets &assets); static int FillAssetForUpload(Asset &asset); static void FillAssetsForUpload(Assets &assets); - static void PrepareToFillAssetFromVBucket(VBucket &vBucket); + static void PrepareToFillAssetFromVBucket(VBucket &vBucket, std::function fillAsset); static void FillAssetFromVBucketFinish(VBucket &vBucket, std::function fillAsset, std::function fillAssets); static bool IsAsset(const Type &type); @@ -64,6 +68,10 @@ public: static void MergeDownloadAsset(std::map &downloadAssets, std::map &mergeAssets); static std::map GenAssetsIndexMap(Assets &assets); + static bool IsVbucketContainsAllPK(const VBucket &vBucket, const std::set &pkSet); + static bool CheckAssetStatus(const Assets &assets); + + static int ConstraintsCheckForCloud(const TableInfo &table, const std::string &trimmedSql); template static int GetValueFromOneField(Type &cloudValue, T &outVal) diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h index 733efd77..c9fada10 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h @@ -34,9 +34,10 @@ public: int ChkSchema(const TableName &tableName, RelationalSchemaObject &localSchema); private: + bool IsAssetPrimaryField(const Field &cloudField); bool CompareType(const FieldInfo &localField, const Field &cloudField); bool CompareNullable(const FieldInfo &localField, const Field &cloudField); - bool CompareIsPrimary(std::map &localPrimaryKeys, const Field &cloudField); + bool ComparePrimaryField(std::map &localPrimaryKeys, const Field &cloudField); int CompareFieldSchema(std::map &primaryKeys, FieldInfoMap &localFields, std::vector &cloudFields); std::shared_ptr cloudSchema_ = nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h index da18258b..4754089a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/icloud_sync_storage_interface.h @@ -82,7 +82,7 @@ public: virtual int PutCloudSyncData(const std::string &tableName, DownloadData &downloadData) = 0; virtual int CleanCloudData(ClearMode mode, const std::vector &tableNameList, - std::vector &assets) = 0; + const RelationalSchemaObject &localSchema, std::vector &assets) = 0; virtual void TriggerObserverAction(const std::string &deviceName, ChangedData &&changedData, bool isChangedData) = 0; @@ -90,6 +90,8 @@ public: virtual int FillCloudAssetForDownload(const std::string &tableName, VBucket &asset, bool isFullReplace) = 0; virtual int FillCloudGidAndAsset(const OpType &opType, const CloudSyncData &data) = 0; + + virtual std::string GetIdentify() const = 0; }; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb.h b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb.h index 05de9409..9ec875dc 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb.h @@ -43,10 +43,6 @@ public: // Register callback invoked when all connections released. virtual void OnClose(const std::function &func) = 0; - virtual void OpenPerformanceAnalysis() = 0; - - virtual void ClosePerformanceAnalysis() = 0; - virtual void WakeUpSyncer() = 0; virtual void SetCorruptHandler(const DatabaseCorruptHandler &handler) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_factory.h b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_factory.h index 2bf9940b..66c2c619 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_factory.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_factory.h @@ -47,10 +47,10 @@ public: virtual IKvDB *CreateKvDb(KvDBType kvDbType, int &errCode) = 0; +#ifndef OMIT_MULTI_VER // Create a key-value database for commit storage module. virtual IKvDB *CreateCommitStorageDB(int &errCode) = 0; -#ifndef OMIT_MULTI_VER // Create the multi version storage for multi version natural store virtual IKvDBMultiVerDataStorage *CreateMultiVerStorage(int &errCode) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h index 669944ef..a5ad5d11 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h @@ -50,6 +50,7 @@ public: // Close and release the connection. virtual int Close() = 0; virtual int SyncToDevice(SyncInfo &info) = 0; + virtual int32_t GetCloudSyncTaskCount() = 0; virtual std::string GetIdentifier() = 0; virtual int CreateDistributedTable(const std::string &tableName, TableSyncType syncType) = 0; virtual int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h index f82fb91b..cf03244a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h @@ -66,7 +66,8 @@ public: int PutCloudSyncData(const std::string &tableName, DownloadData &downloadData); - int CleanCloudData(ClearMode mode, const std::vector &tableNameList, std::vector &assets); + int CleanCloudData(ClearMode mode, const std::vector &tableNameList, + const RelationalSchemaObject &localSchema, std::vector &assets); int CheckSchema(const TableName &tableName) const; @@ -83,6 +84,8 @@ public: int FillCloudGidAndAsset(const OpType &opType, const CloudSyncData &data); + std::string GetIdentify() const; + protected: void Init(); private: diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h b/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h index da94c92f..0d01835a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h @@ -149,6 +149,11 @@ public: { return -E_NOT_SUPPORT; } + + virtual int TryHandle() const + { + return E_OK; + } }; } #endif // SYNC_GENERIC_INTERFACE_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp index 49863758..ff291ec3 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp @@ -306,7 +306,7 @@ std::map CloudStorageUtils::GetCloudPrimaryKeyFieldMap(const return pkMap; } -int CloudStorageUtils::CheckAssetFromSchema(const TableSchema &tableSchema, VBucket &vBucket, +int CloudStorageUtils::GetAssetFieldsFromSchema(const TableSchema &tableSchema, VBucket &vBucket, std::vector &fields) { for (const auto &field: tableSchema.fields) { @@ -317,17 +317,9 @@ int CloudStorageUtils::CheckAssetFromSchema(const TableSchema &tableSchema, VBuc if (it->second.index() != TYPE_INDEX && it->second.index() != TYPE_INDEX) { continue; } - if (field.type == TYPE_INDEX) { - auto assets = std::get_if(&it->second); - if (assets != nullptr && assets->size() == 1) { - Asset asset = (*assets)[0]; - vBucket[field.colName] = asset; - } - } fields.push_back(field); } - if (fields.size() == 0) { - LOGE("No assets need to be filled."); + if (fields.empty()) { return -E_CLOUD_ERROR; } return E_OK; @@ -384,33 +376,95 @@ AssetStatus CloudStorageUtils::FlagToStatus(AssetOpType opType) } } -int CloudStorageUtils::FillAssetForDownload(Asset &asset) +void CloudStorageUtils::ChangeAssetsOnVBucketToAsset(VBucket &vBucket, std::vector &fields) +{ + for (const Field &field: fields) { + if (field.type == TYPE_INDEX) { + Type asset = GetAssetFromAssets(vBucket[field.colName]); + vBucket[field.colName] = asset; + } + } +} + +Type CloudStorageUtils::GetAssetFromAssets(Type &value) +{ + Asset assetVal; + int errCode = GetValueFromType(value, assetVal); + if (errCode == E_OK) { + return assetVal; + } + + Assets assets; + errCode = GetValueFromType(value, assets); + if (errCode != E_OK) { + return Nil(); + } + + for (Asset &asset: assets) { + if (asset.flag != static_cast(AssetOpType::DELETE)) { + return std::move(asset); + } + } + return Nil(); +} + +void CloudStorageUtils::FillAssetBeforeDownload(Asset &asset) { AssetOpType flag = static_cast(asset.flag); AssetStatus status = static_cast(asset.status); switch (flag) { case AssetOpType::INSERT: { - if (status == AssetStatus::DOWNLOADING || status == AssetStatus::ABNORMAL) { + if (status != AssetStatus::NORMAL) { asset.hash = std::string(""); } break; } - case AssetOpType::DELETE: { - if (status == AssetStatus::NORMAL) { - return -E_NOT_FOUND; + default: + break; + } +} + +void CloudStorageUtils::FillAssetAfterDownloadFail(Asset &asset) +{ + AssetOpType flag = static_cast(asset.flag); + AssetStatus status = static_cast(asset.status); + switch (flag) { + case AssetOpType::INSERT: + case AssetOpType::DELETE: + case AssetOpType::UPDATE: { + if (status != AssetStatus::NORMAL) { + asset.hash = std::string(""); + asset.status = static_cast(AssetStatus::ABNORMAL); } break; } default: break; } +} + +int CloudStorageUtils::FillAssetAfterDownload(Asset &asset) +{ + AssetOpType flag = static_cast(asset.flag); + switch (flag) { + case AssetOpType::INSERT: + case AssetOpType::UPDATE: { + asset.status = static_cast(AssetStatus::NORMAL); + break; + } + case AssetOpType::DELETE: { + return -E_NOT_FOUND; + } + default: + break; + } return E_OK; } -void CloudStorageUtils::FillAssetsForDownload(Assets &assets) +void CloudStorageUtils::FillAssetsAfterDownload(Assets &assets) { for (auto asset = assets.begin(); asset != assets.end();) { - if (FillAssetForDownload(*asset) == -E_NOT_FOUND) { + if (FillAssetAfterDownload(*asset) == -E_NOT_FOUND) { asset = assets.erase(asset); } else { asset++; @@ -448,19 +502,19 @@ void CloudStorageUtils::FillAssetsForUpload(Assets &assets) } } -void CloudStorageUtils::PrepareToFillAssetFromVBucket(VBucket &vBucket) +void CloudStorageUtils::PrepareToFillAssetFromVBucket(VBucket &vBucket, std::function fillAsset) { for (auto &item: vBucket) { if (IsAsset(item.second)) { Asset asset; GetValueFromType(item.second, asset); - FillAssetForDownload(asset); + fillAsset(asset); vBucket[item.first] = asset; } else if (IsAssets(item.second)) { Assets assets; GetValueFromType(item.second, assets); for (auto &asset: assets) { - FillAssetForDownload(asset); + fillAsset(asset); } vBucket[item.first] = assets; } @@ -545,6 +599,7 @@ bool CloudStorageUtils::IsAssetsContainDuplicateAsset(Assets &assets) std::set set; for (const auto &asset : assets) { if (set.find(asset.name) != set.end()) { + LOGE("assets contain duplicate Asset"); return true; } set.insert(asset.name); @@ -554,14 +609,19 @@ bool CloudStorageUtils::IsAssetsContainDuplicateAsset(Assets &assets) void CloudStorageUtils::EraseNoChangeAsset(std::map &assetsMap) { - for (auto &items: assetsMap) { - for (auto item = items.second.begin(); item != items.second.end();) { - if (static_cast((*item).status) == AssetOpType::NO_CHANGE) { - item = items.second.erase(item); + for (auto items = assetsMap.begin(); items != assetsMap.end();) { + for (auto item = items->second.begin(); item != items->second.end();) { + if (static_cast((*item).flag) == AssetOpType::NO_CHANGE) { + item = items->second.erase(item); } else { item++; } } + if (items->second.empty()) { + items = assetsMap.erase(items); + } else { + items++; + } } } @@ -593,4 +653,63 @@ std::map CloudStorageUtils::GenAssetsIndexMap(Assets &asset } return assetsIndexMap; } + +bool CloudStorageUtils::IsVbucketContainsAllPK(const VBucket &vBucket, const std::set &pkSet) +{ + if (pkSet.empty()) { + return false; + } + for (const auto &pk : pkSet) { + if (vBucket.find(pk) == vBucket.end()) { + return false; + } + } + return true; +} + +static bool IsViolationOfConstraints(const std::string &name, const std::vector &fieldInfos) +{ + for (const auto &field : fieldInfos) { + if (name == field.GetFieldName()) { + if (field.GetStorageType() == StorageType::STORAGE_TYPE_REAL) { + LOGE("[ConstraintsCheckForCloud] Not support create distributed table with real primary key."); + return true; + } else if (field.IsAssetType() || field.IsAssetsType()) { + LOGE("[ConstraintsCheckForCloud] Not support create distributed table with asset primary key."); + return true; + } else { + return false; + } + } + } + return false; +} + +int CloudStorageUtils::ConstraintsCheckForCloud(const TableInfo &table, const std::string &trimmedSql) +{ + if (DBCommon::HasConstraint(trimmedSql, "UNIQUE", " ,", " ,)(")) { + LOGE("[ConstraintsCheckForCloud] Not support create distributed table with 'UNIQUE' constraint."); + return -E_NOT_SUPPORT; + } + + const std::map &primaryKeys = table.GetPrimaryKey(); + const std::vector &fieldInfos = table.GetFieldInfos(); + for (const auto &item : primaryKeys) { + if (IsViolationOfConstraints(item.second, fieldInfos)) { + return -E_NOT_SUPPORT; + } + } + return E_OK; +} + +bool CloudStorageUtils::CheckAssetStatus(const Assets &assets) +{ + for (const Asset &asset: assets) { + if (asset.status > static_cast(AssetStatus::UPDATE)) { + LOGE("assets contain invalid status:[%u]", asset.status); + return false; + } + } + return true; +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp index 19bcc15c..c6be15ec 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp @@ -32,15 +32,19 @@ int SchemaMgr::ChkSchema(const TableName &tableName, RelationalSchemaObject &loc LOGE("Cloud schema has not been set"); return -E_SCHEMA_MISMATCH; } + TableInfo tableInfo = localSchema.GetTable(tableName); + if (tableInfo.Empty()) { + LOGE("Local schema does not contain certain table"); + return -E_SCHEMA_MISMATCH; + } + if (tableInfo.GetTableSyncType() != TableSyncType::CLOUD_COOPERATION) { + LOGE("Sync type of local table is not CLOUD_COOPERATION"); + return -E_NOT_SUPPORT; + } TableSchema cloudTableSchema; int ret = GetCloudTableSchema(tableName, cloudTableSchema); if (ret != E_OK) { - LOGE("Cloud schema does not contain certain table:%d", -E_SCHEMA_MISMATCH); - return -E_SCHEMA_MISMATCH; - } - TableInfo tableInfo = localSchema.GetTable(tableName); - if (tableInfo.Empty()) { - LOGE("Local schema does not contain certain table:%d", -E_SCHEMA_MISMATCH); + LOGE("Cloud schema does not contain certain table:%d", ret); return -E_SCHEMA_MISMATCH; } std::map primaryKeys = tableInfo.GetPrimaryKey(); @@ -54,20 +58,24 @@ int SchemaMgr::CompareFieldSchema(std::map &primaryKeys, FieldIn std::unordered_set cloudColNames; for (const Field &cloudField : cloudFields) { if (localFields.find(cloudField.colName) == localFields.end()) { - LOGE("Column name mismatch between local and cloud schema: %d", -E_SCHEMA_MISMATCH); + LOGE("Column name mismatch between local and cloud schema"); + return -E_SCHEMA_MISMATCH; + } + if (IsAssetPrimaryField(cloudField)) { + LOGE("Asset type can not be primary field"); return -E_SCHEMA_MISMATCH; } FieldInfo &localField = localFields[cloudField.colName]; if (!CompareType(localField, cloudField)) { - LOGE("Type mismatch between local and cloud schema : %d", -E_SCHEMA_MISMATCH); + LOGE("Type mismatch between local and cloud schema"); return -E_SCHEMA_MISMATCH; } if (!CompareNullable(localField, cloudField)) { - LOGE("The nullable property is mismatched between local and cloud schema : %d", -E_SCHEMA_MISMATCH); + LOGE("The nullable property is mismatched between local and cloud schema"); return -E_SCHEMA_MISMATCH; } - if (!CompareIsPrimary(primaryKeys, cloudField)) { - LOGE("The primary key property is mismatched between local and cloud schema : %d", -E_SCHEMA_MISMATCH); + if (!ComparePrimaryField(primaryKeys, cloudField)) { + LOGE("The primary key property is mismatched between local and cloud schema"); return -E_SCHEMA_MISMATCH; } cloudColNames.emplace(cloudField.colName); @@ -80,14 +88,18 @@ int SchemaMgr::CompareFieldSchema(std::map &primaryKeys, FieldIn if (!fieldInfo.HasDefaultValue() && fieldInfo.IsNotNull() && cloudColNames.find(fieldName) == cloudColNames.end()) { - LOGE("Column from local schema is not within cloud schema but doesn't have default value : %d", - -E_SCHEMA_MISMATCH); + LOGE("Column from local schema is not within cloud schema but doesn't have default value"); return -E_SCHEMA_MISMATCH; } } return E_OK; } +bool SchemaMgr::IsAssetPrimaryField(const Field &cloudField) +{ + return cloudField.primary && (cloudField.type == TYPE_INDEX || cloudField.type == TYPE_INDEX); +} + bool SchemaMgr::CompareType(const FieldInfo &localField, const Field &cloudField) { StorageType localType = localField.GetStorageType(); @@ -118,7 +130,7 @@ bool SchemaMgr::CompareNullable(const FieldInfo &localField, const Field &cloudF return localField.IsNotNull() == !cloudField.nullable; } -bool SchemaMgr::CompareIsPrimary(std::map &localPrimaryKeys, const Field &cloudField) +bool SchemaMgr::ComparePrimaryField(std::map &localPrimaryKeys, const Field &cloudField) { // whether the corresponding field in local schema is primary key bool isLocalFieldPrimary = false; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.cpp index 4b143eee..a6f5fcfc 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.cpp @@ -15,7 +15,6 @@ #ifdef RELATIONAL_STORE #include "data_transformer.h" -#include "db_common.h" #include "db_errno.h" #include "log_print.h" #include "parcel.h" @@ -40,8 +39,7 @@ int DataTransformer::TransformTableData(const TableDataWithLog &tableDataWithLog } int DataTransformer::TransformDataItem(const std::vector &dataItems, - const std::vector &remoteFieldInfo, const std::vector &localFieldInfo, - OptTableDataWithLog &tableDataWithLog) + const std::vector &remoteFieldInfo, OptTableDataWithLog &tableDataWithLog) { if (dataItems.empty()) { return E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h index e2639f7a..6498006f 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/data_transformer.h @@ -68,7 +68,7 @@ public: static int TransformTableData(const TableDataWithLog &tableDataWithLog, const std::vector &fieldInfoList, std::vector &dataItems); static int TransformDataItem(const std::vector &dataItems, const std::vector &remoteFieldInfo, - const std::vector &localFieldInfo, OptTableDataWithLog &tableDataWithLog); + OptTableDataWithLog &tableDataWithLog); static int SerializeDataItem(const RowDataWithLog &data, const std::vector &fieldInfo, DataItem &dataItem); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.cpp index 0667c552..8c57e89f 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.cpp @@ -32,8 +32,10 @@ namespace DistributedDB { IKvDB *DefaultFactory::CreateKvDb(KvDBType kvDbType, int &errCode) { switch (kvDbType) { +#ifndef OMIT_MULTI_VER case LOCAL_KVDB: return CreateLocalKvDB(errCode); +#endif case SINGER_VER_KVDB: return CreateSingleVerNaturalStore(errCode); #ifndef OMIT_MULTI_VER @@ -46,6 +48,7 @@ IKvDB *DefaultFactory::CreateKvDb(KvDBType kvDbType, int &errCode) } } +#ifndef OMIT_MULTI_VER IKvDB *DefaultFactory::CreateLocalKvDB(int &errCode) { IKvDB *kvDb = new (std::nothrow) SQLiteLocalKvDB(); @@ -53,7 +56,6 @@ IKvDB *DefaultFactory::CreateLocalKvDB(int &errCode) return kvDb; } -#ifndef OMIT_MULTI_VER // Create the multi-version natural store, it contains a commit version and commit storage kvdb. IKvDB *DefaultFactory::CreateMultiVerNaturalStore(int &errCode) { @@ -71,11 +73,13 @@ IKvDB *DefaultFactory::CreateSingleVerNaturalStore(int &errCode) return kvDb; } +#ifndef OMIT_MULTI_VER // Create a key-value database for commit storage module. IKvDB *DefaultFactory::CreateCommitStorageDB(int &errCode) { return CreateLocalKvDB(errCode); } +#endif #ifndef OMIT_MULTI_VER IKvDBMultiVerDataStorage *DefaultFactory::CreateMultiVerStorage(int &errCode) diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.h b/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.h index b86dcf01..86a0b748 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/default_factory.h @@ -28,10 +28,10 @@ public: DISABLE_COPY_ASSIGN_MOVE(DefaultFactory); IKvDB *CreateKvDb(KvDBType kvDbType, int &errCode) override; +#ifndef OMIT_MULTI_VER // Create a key-value database for commit storage module. IKvDB *CreateCommitStorageDB(int &errCode) override; -#ifndef OMIT_MULTI_VER // Create the multi version storage for multi version natural store IKvDBMultiVerDataStorage *CreateMultiVerStorage(int &errCode) override; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.cpp index 13544d3e..19b3fb43 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.cpp @@ -264,6 +264,7 @@ KvDBProperties &GenericKvDB::MyProp() return properties_; } +#ifndef OMIT_MULTI_VER int GenericKvDB::GetWorkDir(const KvDBProperties &kvDBProp, std::string &workDir) { std::string origDataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, ""); @@ -275,6 +276,7 @@ int GenericKvDB::GetWorkDir(const KvDBProperties &kvDBProp, std::string &workDir workDir = origDataDir + "/" + identifierDir; return E_OK; } +#endif void GenericKvDB::SetCorruptHandler(const DatabaseCorruptHandler &handler) { @@ -282,20 +284,6 @@ void GenericKvDB::SetCorruptHandler(const DatabaseCorruptHandler &handler) corruptHandler_ = handler; } -void GenericKvDB::OpenPerformanceAnalysis() -{ - if (performance_ != nullptr) { - performance_->OpenPerformanceAnalysis(); - } -} - -void GenericKvDB::ClosePerformanceAnalysis() -{ - if (performance_ != nullptr) { - performance_->ClosePerformanceAnalysis(); - } -} - void GenericKvDB::CommitNotifyAsync(int notifyEvent, KvDBCommitNotifyFilterAbleData *data) { notificationChain_->NotifyEvent(static_cast(notifyEvent), data); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.h b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.h index d75b4aa9..f0f86e8e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/generic_kvdb.h @@ -98,10 +98,6 @@ public: // Get event notify counter. uint64_t GetEventNotifyCounter() const; - void OpenPerformanceAnalysis() override; - - void ClosePerformanceAnalysis() override; - void WakeUpSyncer() override {}; void EnableAutonomicUpgrade() override {}; @@ -155,7 +151,9 @@ protected: const KvDBProperties &MyProp() const; KvDBProperties &MyProp(); +#ifndef OMIT_MULTI_VER static int GetWorkDir(const KvDBProperties &kvDBProp, std::string &workDir); +#endif void CorruptNotify() const; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp index 40bce7c0..95bbc0d2 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kvdb_manager.cpp @@ -35,7 +35,9 @@ namespace { DefaultFactory g_defaultFactory; static const KvDBType g_dbTypeArr[] = { +#ifndef OMIT_MULTI_VER LOCAL_KVDB, +#endif // OMIT_MULTI_VER SINGER_VER_KVDB, #ifndef OMIT_MULTI_VER MULTI_VER_KVDB @@ -51,10 +53,14 @@ namespace { int errCode = E_OK; int databaseType = property.GetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::LOCAL_TYPE); if (databaseType == KvDBProperties::LOCAL_TYPE) { +#ifndef OMIT_MULTI_VER kvDB = factory->CreateKvDb(LOCAL_KVDB, errCode); if (kvDB != nullptr) { kvDB->EnableAutonomicUpgrade(); } +#else + return -E_NOT_SUPPORT; +#endif // OMIT_MULTI_VER } else if (databaseType == KvDBProperties::SINGLE_VER_TYPE) { kvDB = factory->CreateKvDb(SINGER_VER_KVDB, errCode); } else { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.cpp index ceede762..2f2426ab 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include "local_database_oper.h" #include "log_print.h" @@ -212,3 +213,4 @@ int LocalDatabaseOper::ImportPostHandle() const return localKvDb_->InitDatabaseContext(localKvDb_->GetDbProperties()); } } // namespace DistributedDB +#endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.h b/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.h index dc0359ed..574b8708 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/operation/local_database_oper.h @@ -16,6 +16,7 @@ #ifndef LOCAL_DATABASE_OPER_H #define LOCAL_DATABASE_OPER_H +#ifndef OMIT_MULTI_VER #include "database_oper.h" #include "sqlite_local_kvdb.h" @@ -54,4 +55,5 @@ private: SQLiteStorageEngine *storageEngine_; }; } // namespace DistributedDB +#endif // OMIT_MULTI_VER #endif // LOCAL_DATABASE_OPER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index 42bc3f4a..68060b3b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -681,27 +681,24 @@ int RelationalSyncAbleStorage::GetCompressionAlgo(std::set &a return E_OK; } -void RelationalSyncAbleStorage::RegisterObserverAction(const RelationalObserverAction &action) +void RelationalSyncAbleStorage::RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action) { std::lock_guard lock(dataChangeDeviceMutex_); - dataChangeDeviceCallback_ = action; + dataChangeCallbackMap_[connectionId] = action; } void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceName, ChangedData &&changedData, bool isChangedData) { - { - std::lock_guard lock(dataChangeDeviceMutex_); - if (!dataChangeDeviceCallback_) { - return; - } - } IncObjRef(this); int taskErrCode = RuntimeContext::GetInstance()->ScheduleTask([this, deviceName, changedData, isChangedData] () mutable { std::lock_guard lock(dataChangeDeviceMutex_); - if (dataChangeDeviceCallback_) { - dataChangeDeviceCallback_(deviceName, std::move(changedData), isChangedData); + if (!dataChangeCallbackMap_.empty()) { + auto it = dataChangeCallbackMap_.rbegin(); // call the last valid observer + if (it->second != nullptr) { + it->second(deviceName, std::move(changedData), isChangedData); + } } DecObjRef(this); }); @@ -899,8 +896,7 @@ int RelationalSyncAbleStorage::StartTransaction(TransactType type) } int errCode = E_OK; auto *handle = static_cast( - storageEngine_->FindExecutor(type == TransactType::IMMEDIATE ? true : false, - OperatePerm::NORMAL_PERM, errCode)); + storageEngine_->FindExecutor(type == TransactType::IMMEDIATE, OperatePerm::NORMAL_PERM, errCode)); if (handle == nullptr) { ReleaseHandle(handle); return errCode; @@ -1099,25 +1095,14 @@ int RelationalSyncAbleStorage::PutCloudSyncData(const std::string &tableName, Do } int RelationalSyncAbleStorage::CleanCloudData(ClearMode mode, const std::vector &tableNameList, - std::vector &assets) + const RelationalSchemaObject &localSchema, std::vector &assets) { if (transactionHandle_ == nullptr) { - LOGE(" the transaction has not been started"); + LOGE("the transaction has not been started"); return -E_INVALID_DB; } - std::vector tableSchemaList; - for (const auto &tableName: tableNameList) { - TableSchema tableSchema; - int errCode = GetCloudTableSchema(tableName, tableSchema); - if (errCode != E_OK) { - LOGE("Get cloud schema failed when clean cloud data, %d", errCode); - // if a table in local which cannot find schema and cloud, not handle. - } else { - tableSchemaList.push_back(tableSchema); - } - } - return transactionHandle_->DoCleanInner(mode, tableNameList, tableSchemaList, assets); + return transactionHandle_->DoCleanInner(mode, tableNameList, localSchema, assets); } int RelationalSyncAbleStorage::GetCloudTableSchema(const TableName &tableName, TableSchema &tableSchema) @@ -1208,5 +1193,22 @@ void RelationalSyncAbleStorage::SetSyncAbleEngine(std::shared_ptrGetIdentifier(); +} +void RelationalSyncAbleStorage::EraseDataChangeCallback(uint64_t connectionId) +{ + std::lock_guard lock(dataChangeDeviceMutex_); + auto it = dataChangeCallbackMap_.find(connectionId); + if (it != dataChangeCallbackMap_.end()) { + dataChangeCallbackMap_.erase(it); + } +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 069a4176..4540da73 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -352,13 +352,16 @@ int SQLiteRelationalStore::Sync(const ISyncer::SyncParma &syncParam, uint64_t co } // Called when a connection released. -void SQLiteRelationalStore::DecreaseConnectionCounter() +void SQLiteRelationalStore::DecreaseConnectionCounter(uint64_t connectionId) { int count = connectionCount_.fetch_sub(1, std::memory_order_seq_cst); if (count <= 0) { LOGF("Decrease db connection counter failed, count <= 0."); return; } + if (storageEngine_ != nullptr) { + storageEngine_->EraseDataChangeCallback(connectionId); + } if (count != 1) { return; } @@ -366,7 +369,6 @@ void SQLiteRelationalStore::DecreaseConnectionCounter() LockObj(); auto notifiers = std::move(closeNotifiers_); UnlockObj(); - for (const auto ¬ifier : notifiers) { if (notifier) { notifier(); @@ -375,9 +377,6 @@ void SQLiteRelationalStore::DecreaseConnectionCounter() // Sync Close syncAbleEngine_->Close(); - if (storageEngine_ != nullptr) { - storageEngine_->RegisterObserverAction(nullptr); - } if (cloudSyncer_ != nullptr) { cloudSyncer_->Close(); @@ -400,7 +399,7 @@ void SQLiteRelationalStore::DecreaseConnectionCounter() DecObjRef(storageEngine_); } -void SQLiteRelationalStore::ReleaseDBConnection(RelationalStoreConnection *connection) +void SQLiteRelationalStore::ReleaseDBConnection(uint64_t connectionId, RelationalStoreConnection *connection) { if (connectionCount_.load() == 1) { sqliteStorageEngine_->SetConnectionFlag(false); @@ -409,7 +408,7 @@ void SQLiteRelationalStore::ReleaseDBConnection(RelationalStoreConnection *conne connectMutex_.lock(); if (connection != nullptr) { KillAndDecObjRef(connection); - DecreaseConnectionCounter(); + DecreaseConnectionCounter(connectionId); connectMutex_.unlock(); KillAndDecObjRef(this); } else { @@ -448,7 +447,14 @@ int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName, } return errCode; } - +int32_t SQLiteRelationalStore::GetCloudSyncTaskCount() +{ + if (cloudSyncer_ == nullptr) { + LOGE("[RelationalStore] cloudSyncer was not initialized when get cloud sync task count."); + return -1; + } + return cloudSyncer_->GetCloudSyncTaskCount(); +} int SQLiteRelationalStore::CleanCloudData(ClearMode mode) { auto tableMode = static_cast(sqliteStorageEngine_->GetProperties().GetIntProp( @@ -457,13 +463,10 @@ int SQLiteRelationalStore::CleanCloudData(ClearMode mode) LOGE("Not support remove device data in collaboration mode."); return -E_NOT_SUPPORT; } - if (cloudSyncer_ == nullptr) { - LOGE("[RelationalStore] cloudSyncer was not initialized when clean cloud data"); - return -E_INVALID_DB; - } - TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); + RelationalSchemaObject localSchema = sqliteStorageEngine_->GetSchema(); + TableInfoMap tables = localSchema.GetTables(); std::vector cloudTableNameList; - for (auto tableInfo: tables) { + for (const auto &tableInfo : tables) { if (tableInfo.second.GetTableSyncType() == CLOUD_COOPERATION) { cloudTableNameList.push_back(tableInfo.first); } @@ -472,7 +475,12 @@ int SQLiteRelationalStore::CleanCloudData(ClearMode mode) LOGI("[RelationalStore] device doesn't has cloud table, clean cloud data finished."); return E_OK; } - int errCode = cloudSyncer_->CleanCloudData(mode, cloudTableNameList); + + if (cloudSyncer_ == nullptr) { + LOGE("[RelationalStore] cloudSyncer was not initialized when clean cloud data"); + return -E_INVALID_DB; + } + int errCode = cloudSyncer_->CleanCloudData(mode, cloudTableNameList, localSchema); if (errCode != E_OK) { LOGE("[RelationalStore] failed to clean cloud data, %d.", errCode); } @@ -541,8 +549,8 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap auto iter = tables.find(tableName); if (tables.empty() || (!tableName.empty() && iter == tables.end())) { - LOGE("Remove device data with table name which is not a distributed table or no distributed table found."); - return -E_DISTRIBUTED_SCHEMA_NOT_FOUND; + LOGI("Remove device data with table name which is not a distributed table or no distributed table found."); + return E_OK; } // cloud mode is not permit if (iter->second.GetTableSyncType() == CLOUD_COOPERATION) { @@ -575,9 +583,9 @@ int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std return RemoveDeviceDataInner(hashDeviceId, device, tableName, isNeedHash); } -void SQLiteRelationalStore::RegisterObserverAction(const RelationalObserverAction &action) +void SQLiteRelationalStore::RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action) { - storageEngine_->RegisterObserverAction(action); + storageEngine_->RegisterObserverAction(connectionId, action); } int SQLiteRelationalStore::StopLifeCycleTimer() diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h index 8c42b40d..b4057c73 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.h @@ -48,9 +48,11 @@ public: int Sync(const ISyncer::SyncParma &syncParam, uint64_t connectionId); + int32_t GetCloudSyncTaskCount(); + int CleanCloudData(ClearMode mode); - void ReleaseDBConnection(RelationalStoreConnection *connection); + void ReleaseDBConnection(uint64_t connectionId, RelationalStoreConnection *connection); void WakeUpSyncer() override; @@ -65,7 +67,7 @@ public: int RemoveDeviceData(); int RemoveDeviceData(const std::string &device, const std::string &tableName); - void RegisterObserverAction(const RelationalObserverAction &action); + void RegisterObserverAction(uint64_t connectionId, const RelationalObserverAction &action); int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier); std::string GetStorePath() const override; @@ -94,7 +96,7 @@ private: void ReleaseResources(); // 1 store 1 connection - void DecreaseConnectionCounter(); + void DecreaseConnectionCounter(uint64_t connectionId); int CheckDBMode(); int GetSchemaFromMeta(RelationalSchemaObject &schema); int SaveSchemaToMeta(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp index 26f39635..d41fc5b9 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp @@ -55,7 +55,7 @@ int SQLiteRelationalStoreConnection::Close() } } - static_cast(store_)->ReleaseDBConnection(this); + static_cast(store_)->ReleaseDBConnection(GetConnectionId(), this); return E_OK; } @@ -171,6 +171,20 @@ int SQLiteRelationalStoreConnection::RemoveDeviceData() return errCode; } +int32_t SQLiteRelationalStoreConnection::GetCloudSyncTaskCount() +{ + auto *store = GetDB(); + if (store == nullptr) { + LOGE("[RelationalConnection] store is null, get DB failed!"); + return -1; + } + int32_t count = store->GetCloudSyncTaskCount(); + if (count == -1) { + LOGE("[RelationalConnection] failed to get cloud sync task count"); + } + return count; +} + int SQLiteRelationalStoreConnection::DoClean(ClearMode mode) { auto *store = GetDB(); @@ -264,7 +278,7 @@ int SQLiteRelationalStoreConnection::RegisterLifeCycleCallback(const DatabaseLif void SQLiteRelationalStoreConnection::RegisterObserverAction(const RelationalObserverAction &action) { - static_cast(store_)->RegisterObserverAction(action); + static_cast(store_)->RegisterObserverAction(GetConnectionId(), action); } int SQLiteRelationalStoreConnection::RemoteQuery(const std::string &device, const RemoteCondition &condition, diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h index 4fd964b1..111b0a77 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h @@ -35,10 +35,10 @@ public: // Close and release the connection. int Close() override; int SyncToDevice(SyncInfo &info) override; + int32_t GetCloudSyncTaskCount() override; std::string GetIdentifier() override; int CreateDistributedTable(const std::string &tableName, TableSyncType syncType) override; int RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier) override; - int DoClean(ClearMode mode) override; int RemoveDeviceData() override; int RemoveDeviceData(const std::string &device) override; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp index 89656b55..08ece26e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp @@ -159,7 +159,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin return -E_TYPE_MISMATCH; } isUpgraded = true; - int errCode = UpgradeDistributedTable(tableName, schemaChanged); + int errCode = UpgradeDistributedTable(tableName, schemaChanged, syncType); if (errCode != E_OK) { LOGE("Upgrade distributed table failed. %d", errCode); return errCode; @@ -220,7 +220,8 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin return errCode; } -int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged) +int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged, + TableSyncType syncType) { LOGD("Upgrade distributed table."); RelationalSchemaObject schema = schema_; @@ -239,7 +240,7 @@ int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::stri auto mode = static_cast(properties_.GetIntProp( RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); - errCode = handle->UpgradeDistributedTable(tableName, mode, schemaChanged, schema); + errCode = handle->UpgradeDistributedTable(tableName, mode, schemaChanged, schema, syncType); if (errCode != E_OK) { LOGE("Upgrade distributed table failed. %d", errCode); (void)handle->Rollback(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h index 97d7e9b5..91bbd82f 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h @@ -54,7 +54,7 @@ private: // For db. int RegisterFunction(sqlite3 *db) const; - int UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged); + int UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged, TableSyncType syncType); int CreateDistributedTable(const std::string &tableName, bool isUpgraded, const std::string &identity, RelationalSchemaObject &schema, TableSyncType tableSyncType); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.cpp index 83036994..1f36d039 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include "sqlite_local_kvdb.h" #include @@ -394,3 +395,4 @@ int SQLiteLocalKvDB::CheckVersionAndUpgradeIfNeed(const OpenDbProperties &openPr DEFINE_OBJECT_TAG_FACILITIES(SQLiteLocalKvDB) } // namespace DistributedDB +#endif // OMIT_MULTI_VER diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.h index 05db1314..ae4f4245 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb.h @@ -16,6 +16,7 @@ #ifndef SQLITE_LOCAL_KV_DB_H #define SQLITE_LOCAL_KV_DB_H +#ifndef OMIT_MULTI_VER #include #include @@ -89,5 +90,5 @@ private: SQLiteStorageEngine *storageEngine_; }; } // namespace DistributedDB - +#endif // OMIT_MULTI_VER #endif // SQLITE_LOCAL_KV_DB_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.cpp index 4379fa68..674b72e2 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include "sqlite_local_kvdb_connection.h" #include @@ -496,3 +497,4 @@ int SQLiteLocalKvDBConnection::CheckDataStatus(const Key &key, const Value &valu return static_cast(kvDB_)->CheckDataStatus(key, value, isDeleted); } } // namespace DistributedDB +#endif // OMIT_MULTI_VER diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.h index f4efd05b..72179df5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_connection.h @@ -16,6 +16,7 @@ #ifndef SQLITE_LOCAL_KV_DB_CONNECTION_H #define SQLITE_LOCAL_KV_DB_CONNECTION_H +#ifndef OMIT_MULTI_VER #include #include @@ -107,5 +108,5 @@ private: std::mutex importMutex_; }; }; // namespace DistributedDB - +#endif // OMIT_MULTI_VER #endif // SQLITE_LOCAL_KV_DB_CONNECTION_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.cpp index 430ebd60..e8094b63 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include "sqlite_local_kvdb_snapshot.h" #include "sqlite_local_kvdb_connection.h" @@ -52,3 +53,4 @@ void SQLiteLocalKvDBSnapshot::Close() } } } // namespace DistributedDB +#endif // OMIT_MULTI_VER diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.h index cc8b7a1c..7d9ca5bd 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_local_kvdb_snapshot.h @@ -16,6 +16,7 @@ #ifndef SQLITE_LOCAL_KV_DB_SNAP_SHOT_H #define SQLITE_LOCAL_KV_DB_SNAP_SHOT_H +#ifndef OMIT_MULTI_VER #include #include "macro_utils.h" @@ -45,5 +46,5 @@ private: IKvDBConnection *connect_; }; } // namespace DistributedDB - +#endif // OMIT_MULTI_VER #endif // SQLITE_LOCAL_KV_DB_SNAP_SHOT_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp index 5b874ca0..37874142 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.cpp @@ -172,7 +172,8 @@ SQLiteSingleVerNaturalStore::SQLiteSingleVerNaturalStore() autoLifeTime_(DBConstant::DEF_LIFE_CYCLE_TIME), createDBTime_(0), dataInterceptor_(nullptr), - maxLogSize_(DBConstant::MAX_LOG_SIZE_DEFAULT) + maxLogSize_(DBConstant::MAX_LOG_SIZE_DEFAULT), + abortPerm_(OperatePerm::NORMAL_PERM) {} SQLiteSingleVerNaturalStore::~SQLiteSingleVerNaturalStore() @@ -1166,6 +1167,14 @@ void SQLiteSingleVerNaturalStore::ReleaseResources() SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT)); notificationConflictEventsRegistered_ = false; } + + { + std::unique_lock migrateLock(migrateMutex_); + migrateCv_.wait(migrateLock, [this] { + return migrateCount_ <= 0; + }); + } + { std::unique_lock lock(engineMutex_); if (storageEngine_ != nullptr) { @@ -1391,6 +1400,7 @@ int SQLiteSingleVerNaturalStore::Rekey(const CipherPassword &passwd) if (errCode != E_OK) { return errCode; } + LOGI("Stop the syncer for rekey"); StopSyncer(true); std::this_thread::sleep_for(std::chrono::milliseconds(5)); // wait for 5 ms @@ -1412,13 +1422,16 @@ int SQLiteSingleVerNaturalStore::Rekey(const CipherPassword &passwd) END: // Only maindb state have existed handle, if rekey fail other state will create error cache db // Abort can forbid get new handle, requesting handle will return BUSY and nullptr handle + AbortHandle(); if (errCode != -E_FORBID_CACHEDB) { storageEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM); } else { storageEngine_->Abort(OperatePerm::REKEY_MONOPOLIZE_PERM); errCode = E_OK; } + storageEngine_->WaitWriteHandleIdle(); StartSyncer(); + EnableHandle(); return errCode; } @@ -1433,13 +1446,7 @@ int SQLiteSingleVerNaturalStore::Export(const std::string &filePath, const Ciphe // Exclusively write resources std::string localDev; - int errCode = GetLocalIdentity(localDev); - if (errCode == -E_NOT_INIT) { - localDev.resize(DEVICE_ID_LEN); - } else if (errCode != E_OK) { - LOGE("Get local dev id err:%d", errCode); - localDev.resize(0); - } + int errCode = GetAndResizeLocalIdentity(localDev); // The write handle is applied to prevent writing data during the export process. SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); @@ -1526,8 +1533,11 @@ int SQLiteSingleVerNaturalStore::Import(const std::string &filePath, const Ciphe END: // restore the storage engine and the syncer. + AbortHandle(); storageEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM); + storageEngine_->WaitWriteHandleIdle(); StartSyncer(); + EnableHandle(); return errCode; } @@ -1913,9 +1923,18 @@ void SQLiteSingleVerNaturalStore::SetConnectionFlag(bool isExisted) const int SQLiteSingleVerNaturalStore::TriggerToMigrateData() const { RefObject::IncObjRef(this); + { + std::unique_lock lock(migrateMutex_); + migrateCount_++; + } int errCode = RuntimeContext::GetInstance()->ScheduleTask( std::bind(&SQLiteSingleVerNaturalStore::AsyncDataMigration, this)); if (errCode != E_OK) { + { + std::unique_lock lock(migrateMutex_); + migrateCount_--; + } + migrateCv_.notify_all(); RefObject::DecObjRef(this); LOGE("[SingleVerNStore] Trigger to migrate data failed : %d.", errCode); } @@ -1987,9 +2006,17 @@ void SQLiteSingleVerNaturalStore::AsyncDataMigration() const bool isLocked = RuntimeContext::GetInstance()->IsAccessControlled(); if (!isLocked) { LOGI("Begin to migrate cache data to manDb asynchronously!"); + // we can't use engineMutex_ here, because ExecuteMigration will call GetHandle, it will lead to crash at + // engineMutex_.lock_shared (void)StorageEngineManager::ExecuteMigration(storageEngine_); } + { + std::unique_lock lock(migrateMutex_); + migrateCount_--; + } + migrateCv_.notify_all(); + RefObject::DecObjRef(this); } @@ -2446,5 +2473,40 @@ int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDe return errCode; } + +void SQLiteSingleVerNaturalStore::AbortHandle() +{ + std::unique_lock lock(abortHandleMutex_); + abortPerm_ = OperatePerm::RESTART_SYNC_PERM; +} + +void SQLiteSingleVerNaturalStore::EnableHandle() +{ + std::unique_lock lock(abortHandleMutex_); + abortPerm_ = OperatePerm::NORMAL_PERM; +} + +int SQLiteSingleVerNaturalStore::TryHandle() const +{ + std::unique_lock lock(abortHandleMutex_); + if (abortPerm_ == OperatePerm::RESTART_SYNC_PERM) { + LOGW("[SingleVerNStore] Restarting sync, handle id[%s] is busy", + DBCommon::TransferStringToHex(storageEngine_->GetIdentifier()).c_str()); + return -E_BUSY; + } + return E_OK; +} + +int SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarget) const +{ + int errCode = GetLocalIdentity(outTarget); + if (errCode == -E_NOT_INIT) { + outTarget.resize(DEVICE_ID_LEN); + } else if (errCode != E_OK) { + LOGE("Get local dev id err:%d", errCode); + outTarget.resize(0); + } + return errCode; +} DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStore) } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h index 077afff2..864cf0ed 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h @@ -194,6 +194,17 @@ public: int IsSupportSubscribe() const override; + void AbortHandle(); + + void EnableHandle(); + + int TryHandle() const override; + +protected: + void AsyncDataMigration() const; + + void ReleaseResources(); + private: struct TransPair { int index; @@ -207,8 +218,6 @@ private: int RegisterNotification(); - void ReleaseResources(); - void InitCurrentMaxStamp(); int SaveSyncDataItems(const QueryObject &query, std::vector &dataItems, const DeviceInfo &deviceInfo, @@ -241,8 +250,6 @@ private: int StopLifeCycleTimer() const; void InitConflictNotifiedFlag(SingleVerNaturalStoreCommitNotifyData *committedData); - void AsyncDataMigration() const; - // Change value that should be amended, and neglect value that is incompatible void CheckAmendValueContentForSyncProcedure(std::vector &dataItems) const; @@ -279,11 +286,16 @@ private: int RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify); + int GetAndResizeLocalIdentity(std::string &outTarget) const; + DECLARE_OBJECT_TAG(SQLiteSingleVerNaturalStore); Timestamp currentMaxTimestamp_ = 0; mutable std::shared_mutex engineMutex_; + mutable std::mutex migrateMutex_; + mutable std::condition_variable migrateCv_; + mutable int migrateCount_ = 0; SQLiteSingleVerStorageEngine *storageEngine_; bool notificationEventsRegistered_; @@ -302,6 +314,9 @@ private: mutable std::shared_mutex dataInterceptorMutex_; PushDataInterceptor dataInterceptor_; std::atomic maxLogSize_; + + mutable std::shared_mutex abortHandleMutex_; + OperatePerm abortPerm_; }; } // namespace DistributedDB #endif // SQLITE_SINGLE_VER_NATURAL_STORE_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp index 7a06386a..24f6afaf 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.cpp @@ -1382,6 +1382,10 @@ SQLiteSingleVerStorageExecutor *SQLiteSingleVerNaturalStoreConnection::GetExecut LOGE("[SingleVerConnection] the store is null"); return nullptr; } + errCode = naturalStore->TryHandle(); + if (errCode != E_OK) { + return nullptr; + } return naturalStore->GetHandle(isWrite, errCode); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 65bfe058..561a630d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -65,8 +65,7 @@ SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecut bindCloudFieldFuncMap_[TYPE_INDEX] = &CloudStorageUtils::BindAsset; } - -int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode) +int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode, TableSyncType syncType) { std::string trimedSql = DBCommon::TrimSpace(table.GetCreateTableSql()); if (DBCommon::HasConstraint(trimedSql, "WITHOUT ROWID", " ),", " ,;")) { @@ -74,7 +73,7 @@ int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode) return -E_NOT_SUPPORT; } - if (mode == DistributedTableMode::COLLABORATION) { + if (mode == DistributedTableMode::COLLABORATION || syncType == CLOUD_COOPERATION) { if (DBCommon::HasConstraint(trimedSql, "CHECK", " ,", " (")) { LOGE("[CreateDistributedTable] Not support create distributed table with 'CHECK' constraint."); return -E_NOT_SUPPORT; @@ -85,13 +84,23 @@ int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode) return -E_NOT_SUPPORT; } - if (DBCommon::HasConstraint(trimedSql, "REFERENCES", " )", " ")) { - LOGE("[CreateDistributedTable] Not support create distributed table with 'FOREIGN KEY' constraint."); - return -E_NOT_SUPPORT; + if (mode == DistributedTableMode::COLLABORATION) { + if (DBCommon::HasConstraint(trimedSql, "REFERENCES", " )", " ")) { + LOGE("[CreateDistributedTable] Not support create distributed table with 'FOREIGN KEY' constraint."); + return -E_NOT_SUPPORT; + } + } + + if (syncType == CLOUD_COOPERATION) { + int errCode = CloudStorageUtils::ConstraintsCheckForCloud(table, trimedSql); + if (errCode != E_OK) { + LOGE("ConstraintsCheckForCloud failed, errCode = %d", errCode); + return errCode; + } } } - if (mode == DistributedTableMode::SPLIT_BY_DEVICE) { + if (mode == DistributedTableMode::SPLIT_BY_DEVICE && syncType == DEVICE_COOPERATION) { if (table.GetPrimaryKey().size() > 1) { LOGE("[CreateDistributedTable] Not support create distributed table with composite primary keys."); return -E_NOT_SUPPORT; @@ -159,12 +168,10 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(Distributed } } - if (syncType != CLOUD_COOPERATION) { - errCode = CheckTableConstraint(table, mode); - if (errCode != E_OK) { - LOGE("[CreateDistributedTable] check table constraint failed."); - return errCode; - } + errCode = CheckTableConstraint(table, mode, syncType); + if (errCode != E_OK) { + LOGE("[CreateDistributedTable] check table constraint failed."); + return errCode; } // create log table @@ -193,7 +200,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(Distributed } int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std::string &tableName, - DistributedTableMode mode, bool &schemaChanged, RelationalSchemaObject &schema) + DistributedTableMode mode, bool &schemaChanged, RelationalSchemaObject &schema, TableSyncType syncType) { if (dbHandle_ == nullptr) { return -E_INVALID_DB; @@ -205,7 +212,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std: return errCode; } - if (CheckTableConstraint(newTableInfo, mode)) { + if (CheckTableConstraint(newTableInfo, mode, syncType)) { LOGE("[UpgradeDistributedTable] Not support create distributed table without rowid."); return -E_NOT_SUPPORT; } @@ -533,10 +540,8 @@ int IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, cloudSyncData.insData.rowid.push_back(*rowid); VBucket asset; CloudStorageUtils::ObtainAssetFromVBucket(data, asset); - if (!asset.empty()) { - cloudSyncData.insData.timestamp.push_back(*timeStamp); - cloudSyncData.insData.assets.push_back(asset); - } + cloudSyncData.insData.timestamp.push_back(*timeStamp); + cloudSyncData.insData.assets.push_back(asset); } cloudSyncData.insData.extend.push_back(log); } else { @@ -1455,11 +1460,11 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUploadCount(const std::string & const Timestamp ×tamp, const bool isCloudForcePush, int64_t &count) { std::string sql = isCloudForcePush ? - ("SELECT count(rowid) from " + DBCommon::GetLogTableName(tableName) - + " where timestamp > ? and (flag & 0x04) != 0x04 and (cloud_gid != ''" + ("SELECT count(rowid) from '" + DBCommon::GetLogTableName(tableName) + + "' where timestamp > ? and (flag & 0x04) != 0x04 and (cloud_gid != ''" " or (cloud_gid == '' and (flag & 0x01) = 0 ));"): - ("SELECT count(rowid) from " + DBCommon::GetLogTableName(tableName) - + " where timestamp > ? and (flag & 0x02) = 0x02 and (cloud_gid != ''" + ("SELECT count(rowid) from '" + DBCommon::GetLogTableName(tableName) + + "' where timestamp > ? and (flag & 0x02) = 0x02 and (cloud_gid != ''" " or (cloud_gid == '' and (flag & 0x01) = 0 ));"); sqlite3_stmt *stmt = nullptr; @@ -1491,8 +1496,8 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudLogGid(const CloudSyncD cloudDataResult.insData.extend.size() != cloudDataResult.insData.rowid.size()) { return -E_INVALID_ARGS; } - std::string sql = "UPDATE " + DBCommon::GetLogTableName(cloudDataResult.tableName) - + " SET cloud_gid = ? where data_key = ? "; + std::string sql = "UPDATE '" + DBCommon::GetLogTableName(cloudDataResult.tableName) + + "' SET cloud_gid = ? where data_key = ? "; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { @@ -1613,6 +1618,9 @@ int SQLiteSingleVerRelationalStorageExecutor::PutVBucketByType(VBucket &vBucket, if (errCode != E_OK) { return errCode; } + if (!CloudStorageUtils::CheckAssetStatus({asset})) { + return -E_CLOUD_INVALID_ASSET; + } vBucket.insert_or_assign(field.colName, asset); } else if (field.type == TYPE_INDEX && cloudValue.index() == TYPE_INDEX) { Assets assets; @@ -1621,9 +1629,11 @@ int SQLiteSingleVerRelationalStorageExecutor::PutVBucketByType(VBucket &vBucket, return errCode; } if (CloudStorageUtils::IsAssetsContainDuplicateAsset(assets)) { - LOGE("assets is contain duplicate Asset"); return -E_CLOUD_ERROR; } + if (!CloudStorageUtils::CheckAssetStatus(assets)) { + return -E_CLOUD_INVALID_ASSET; + } vBucket.insert_or_assign(field.colName, assets); } else { vBucket.insert_or_assign(field.colName, cloudValue); @@ -1667,7 +1677,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetInfoByPrimaryKeyOrGid(const Tab break; } } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - alreadyFound ? errCode = E_OK : errCode = -E_NOT_FOUND; + errCode = alreadyFound ? E_OK : -E_NOT_FOUND; break; } else { LOGE("SQLite step failed when query log for cloud sync:%d", errCode); @@ -1807,7 +1817,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogStatement(const TableSc } std::vector hashValue; - if (pkSet.size() > 0) { + if (!pkSet.empty()) { errCode = GetPrimaryKeyHashValue(vBucket, tableSchema, hashValue, true); } if (errCode != E_OK) { @@ -1892,7 +1902,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ExecutePutCloudData(const std::str } int SQLiteSingleVerRelationalStorageExecutor::DoCleanInner(ClearMode mode, - const std::vector &tableNameList, const std::vector &tableSchemaList, + const std::vector &tableNameList, const RelationalSchemaObject &localSchema, std::vector &assets) { int errCode = SetLogTriggerStatus(false); @@ -1907,7 +1917,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanInner(ClearMode mode, return errCode; } } else if (mode == FLAG_AND_DATA) { - errCode = DoCleanLogAndData(tableNameList, tableSchemaList, assets); + errCode = DoCleanLogAndData(tableNameList, localSchema, assets); if (errCode != E_OK) { LOGE("[Storage Executor] Failed to do clean log and data when clean cloud data."); return errCode; @@ -1941,7 +1951,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanLogs(const std::vector &dataKeys) { sqlite3_stmt *selectStmt = nullptr; - std::string sql = "SELECT DATA_KEY FROM " + logTableName + " WHERE " + CLOUD_GID_FIELD + + std::string sql = "SELECT DATA_KEY FROM '" + logTableName + "' WHERE " + CLOUD_GID_FIELD + " is not NULL and " + CLOUD_GID_FIELD + " != '' AND " + FLAG_IS_CLOUD + ";"; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, selectStmt); @@ -1990,12 +2000,12 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCleanCloudDataKeys(const std::s break; } } while (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)); - + SQLiteUtils::ResetStatement(selectStmt, true, errCode); return (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) ? E_OK : errCode; } int SQLiteSingleVerRelationalStorageExecutor::DoCleanLogAndData(const std::vector &tableNameList, - const std::vector &tableSchemaList, std::vector &assets) + const RelationalSchemaObject &localSchema, std::vector &assets) { int errCode = E_OK; for (size_t i = 0; i < tableNameList.size(); i++) { @@ -2007,18 +2017,9 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanLogAndData(const std::vecto LOGE("[Storage Executor] Failed to get clean cloud data keys, %d.", errCode); return errCode; } - std::vector assetFields; - int index = 0; - for (const auto &field : tableSchemaList[i].fields) { - if (field.type == TYPE_INDEX || field.type == TYPE_INDEX) { - AssetField assetField; - assetField.field = field; - assetField.index = index; - assetFields.push_back(assetField); - } - index++; - } - errCode = GetCloudAssets(tableName, assetFields, dataKeys, assets); + + std::vector fieldInfos = localSchema.GetTable(tableName).GetFieldInfos(); + errCode = GetCloudAssets(tableName, fieldInfos, dataKeys, assets); if (errCode != E_OK) { LOGE("[Storage Executor] failed to get cloud assets when clean cloud data, %d", errCode); return errCode; @@ -2035,12 +2036,12 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanLogAndData(const std::vecto } int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssetOnTable(const std::string &tableName, - const AssetField &assetField, const std::vector &datakeys, std::vector &assets) + const std::string &fieldName, const std::vector &dataKeys, std::vector &assets) { int errCode = E_OK; - for (const auto &rowId: datakeys) { - std::string queryAssetSql = "SELECT " + assetField.field.colName + " FROM " + tableName + - " WHERE " + ROWID + " = " + std::to_string(rowId) + ";"; + for (const auto &rowId : dataKeys) { + std::string queryAssetSql = "SELECT " + fieldName + " FROM '" + tableName + + "' WHERE " + ROWID + " = " + std::to_string(rowId) + ";"; sqlite3_stmt *selectStmt = nullptr; errCode = SQLiteUtils::GetStatement(dbHandle_, queryAssetSql, selectStmt); if (errCode != E_OK) { @@ -2051,7 +2052,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssetOnTable(const std::st errCode = SQLiteUtils::StepWithRetry(selectStmt); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { std::vector blobValue; - errCode = SQLiteUtils::GetColumnBlobValue(selectStmt, assetField.index, blobValue); + errCode = SQLiteUtils::GetColumnBlobValue(selectStmt, 0, blobValue); if (errCode != E_OK) { SQLiteUtils::ResetStatement(selectStmt, true, errCode); return errCode; @@ -2070,13 +2071,13 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssetOnTable(const std::st } int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssetsOnTable(const std::string &tableName, - const AssetField &assetField, const std::vector &datakeys, std::vector &assets) + const std::string &fieldName, const std::vector &dataKeys, std::vector &assets) { int errCode = E_OK; int ret = E_OK; sqlite3_stmt *selectStmt = nullptr; - for (const auto &rowId: datakeys) { - std::string queryAssetsSql = "SELECT " + assetField.field.colName + " FROM " + tableName + + for (const auto &rowId : dataKeys) { + std::string queryAssetsSql = "SELECT " + fieldName + " FROM " + tableName + " WHERE " + ROWID + " = " + std::to_string(rowId) + ";"; errCode = SQLiteUtils::GetStatement(dbHandle_, queryAssetsSql, selectStmt); if (errCode != E_OK) { @@ -2086,7 +2087,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssetsOnTable(const std::s errCode = SQLiteUtils::StepWithRetry(selectStmt); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { std::vector blobValue; - errCode = SQLiteUtils::GetColumnBlobValue(selectStmt, assetField.index, blobValue); + errCode = SQLiteUtils::GetColumnBlobValue(selectStmt, 0, blobValue); if (errCode != E_OK) { goto END; } @@ -2108,25 +2109,22 @@ END: } int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssets(const std::string &tableName, - const std::vector assetFields, const std::vector &datakeys, std::vector &assets) + const std::vector &fieldInfos, const std::vector &dataKeys, std::vector &assets) { int errCode = E_OK; - for (const AssetField &assetField: assetFields) { - if (assetField.field.type == TYPE_INDEX) { - errCode = GetCloudAssetOnTable(tableName, assetField, datakeys, assets); + for (const auto &fieldInfo: fieldInfos) { + if (fieldInfo.IsAssetType()) { + errCode = GetCloudAssetOnTable(tableName, fieldInfo.GetFieldName(), dataKeys, assets); if (errCode != E_OK) { LOGE("[Storage Executor] failed to get cloud asset on table, %d.", errCode); return errCode; } - } else if (assetField.field.type == TYPE_INDEX) { - errCode = GetCloudAssetsOnTable(tableName, assetField, datakeys, assets); + } else if (fieldInfo.IsAssetsType()) { + errCode = GetCloudAssetsOnTable(tableName, fieldInfo.GetFieldName(), dataKeys, assets); if (errCode != E_OK) { LOGE("[Storage Executor] failed to get cloud assets on table, %d.", errCode); return errCode; } - } else { - LOGD("[Storage Executor] get cloud assets when fields are neither Asset nor Assets is not supported."); - return -E_INTERNAL_ERROR; } } return errCode; @@ -2175,7 +2173,7 @@ int SQLiteSingleVerRelationalStorageExecutor::InsertCloudData(const std::string LOGE("Get insert statement failed when save cloud data, %d", errCode); return errCode; } - CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket); + CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); errCode = BindValueToUpsertStatement(vBucket, tableSchema.fields, insertStmt); if (errCode != E_OK) { SQLiteUtils::ResetStatement(insertStmt, true, errCode); @@ -2439,7 +2437,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateDataTableStatement(const int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudData(const std::string &tableName, VBucket &vBucket, const TableSchema &tableSchema) { - CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket); + CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetBeforeDownload); sqlite3_stmt *updateStmt = nullptr; int errCode = GetUpdateDataTableStatement(vBucket, tableSchema, updateStmt); if (errCode != E_OK) { @@ -2613,13 +2611,25 @@ int SQLiteSingleVerRelationalStorageExecutor::GetDeleteStatementForCloudSync(con return -E_CLOUD_ERROR; } + bool queryByPk = CloudStorageUtils::IsVbucketContainsAllPK(vBucket, pkSet); std::string deleteSql = "delete from " + tableSchema.name; - deleteSql += GetWhereConditionForDataTable(gidStr, pkSet, tableSchema.name, false); + deleteSql += GetWhereConditionForDataTable(gidStr, pkSet, tableSchema.name, queryByPk); errCode = SQLiteUtils::GetStatement(dbHandle_, deleteSql, deleteStmt); if (errCode != E_OK) { LOGE("Get delete statement failed when delete data, %d, deleteSql = %s", errCode, deleteSql.c_str()); + return errCode; } - return errCode; + + int ret = E_OK; + if (!pkSet.empty() && queryByPk) { + std::vector pkFields = CloudStorageUtils::GetCloudPrimaryKeyField(tableSchema); + errCode = BindValueToUpsertStatement(vBucket, pkFields, deleteStmt); + if (errCode != E_OK) { + LOGE("bind value to delete statement failed when delete cloud data, %d", errCode); + SQLiteUtils::ResetStatement(deleteStmt, true, ret); + } + } + return errCode != E_OK ? errCode : ret; } int SQLiteSingleVerRelationalStorageExecutor::DeleteCloudData(const std::string &tableName, const VBucket &vBucket, diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index cba0db78..5f26987b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -44,7 +44,7 @@ public: TableInfo &table, TableSyncType syncType); int UpgradeDistributedTable(const std::string &tableName, DistributedTableMode mode, bool &schemaChanged, - RelationalSchemaObject &schema); + RelationalSchemaObject &schema, TableSyncType syncType); int StartTransaction(TransactType type); int Commit(); @@ -107,7 +107,7 @@ public: int FillCloudAssetForDownload(const TableSchema &tableSchema, VBucket &vBucket, bool isFullReplace); int DoCleanInner(ClearMode mode, const std::vector &tableNameList, - const std::vector &tableSchemaList, std::vector &assets); + const RelationalSchemaObject &localSchema, std::vector &assets); int FillCloudAssetForUpload(const std::string &tableName, const CloudSyncBatch &data); @@ -115,7 +115,7 @@ private: int DoCleanLogs(const std::vector &tableNameList); int DoCleanLogAndData(const std::vector &tableNameList, - const std::vector &tableSchemaList, std::vector &assets); + const RelationalSchemaObject &localSchema, std::vector &assets); int CleanCloudDataOnLogTable(const std::string &logTableName); @@ -123,14 +123,14 @@ private: int GetCleanCloudDataKeys(const std::string &logTableName, std::vector &dataKeys); - int GetCloudAssets(const std::string &tableName, const std::vector assetFields, - const std::vector &datakeys, std::vector &assets); + int GetCloudAssets(const std::string &tableName, const std::vector &fieldInfos, + const std::vector &dataKeys, std::vector &assets); - int GetCloudAssetOnTable(const std::string &tableName, - const AssetField &assetField, const std::vector &datakeys, std::vector &assets); + int GetCloudAssetOnTable(const std::string &tableName, const std::string &fieldName, + const std::vector &dataKeys, std::vector &assets); - int GetCloudAssetsOnTable(const std::string &tableName, - const AssetField &assetField, const std::vector &datakeys, std::vector &assets); + int GetCloudAssetsOnTable(const std::string &tableName, const std::string &fieldName, + const std::vector &dataKeys, std::vector &assets); int GetDataItemForSync(sqlite3_stmt *statement, DataItem &dataItem, bool isGettingDeletedData) const; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp index db88d3d8..1fdc6414 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_extend_executor.cpp @@ -127,10 +127,12 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForDownload(const Ta return errCode; } std::vector assetsField; - errCode = CloudStorageUtils::CheckAssetFromSchema(tableSchema, vBucket, assetsField); + errCode = CloudStorageUtils::GetAssetFieldsFromSchema(tableSchema, vBucket, assetsField); if (errCode != E_OK) { + LOGE("No assets need to be filled."); goto END; } + CloudStorageUtils::ChangeAssetsOnVBucketToAsset(vBucket, assetsField); int64_t rowId; errCode = GetQueryLogRowid(tableSchema.name, vBucket, rowId); @@ -138,10 +140,10 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForDownload(const Ta goto END; } if (isFullReplace) { - CloudStorageUtils::FillAssetFromVBucketFinish(vBucket, CloudStorageUtils::FillAssetForDownload, - CloudStorageUtils::FillAssetsForDownload); + CloudStorageUtils::FillAssetFromVBucketFinish(vBucket, CloudStorageUtils::FillAssetAfterDownload, + CloudStorageUtils::FillAssetsAfterDownload); } else { - CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket); + CloudStorageUtils::PrepareToFillAssetFromVBucket(vBucket, CloudStorageUtils::FillAssetAfterDownloadFail); } errCode = GetFillDownloadAssetStatement(tableSchema.name, vBucket, assetsField, stmt); if (errCode != E_OK) { @@ -171,7 +173,7 @@ END: int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(const std::string &tableName, const CloudSyncBatch &data) { - if (data.assets.empty() || data.rowid.empty() || data.timestamp.empty()) { + if (data.rowid.empty() || data.timestamp.empty()) { return -E_INVALID_ARGS; } if (data.assets.size() != data.rowid.size() || data.assets.size() != data.timestamp.size()) { @@ -184,6 +186,9 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(const std: } sqlite3_stmt *stmt = nullptr; for (size_t i = 0; i < data.assets.size(); ++i) { + if (data.assets.at(i).empty()) { + continue; + } errCode = InitFillUploadAssetStatement(tableName, data, i, stmt); if (errCode != E_OK) { break; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp index 3282948c..5a2227d6 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp @@ -566,6 +566,7 @@ void SQLiteSingleVerStorageEngine::EndMigrate(SQLiteSingleVerStorageExecutor *&h if (errCode != E_OK) { LOGE("Add subscribe trigger after migrate sync data failed: %d", errCode); } + // Notify max timestamp offset for SyncEngine. // When time change offset equals 0, SyncEngine can adjust local time offset according to max timestamp. RuntimeContext::GetInstance()->NotifyTimestampChanged(0); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp index b56bb223..59dfe0b1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp @@ -1365,7 +1365,7 @@ void SQLiteUtils::GetRawSysTime(sqlite3_context *ctx, int argc, sqlite3_value ** uint64_t curTime = 0; int errCode = TimeHelper::GetSysCurrentRawTime(curTime); if (errCode != E_OK) { - sqlite3_result_error(ctx, "get raw sys time failed.", errCode); + sqlite3_result_error(ctx, "get raw sys time failed in sqlite utils.", errCode); return; } sqlite3_result_int64(ctx, (sqlite3_int64)(curTime)); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp index 32491ba7..558ecc4a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp @@ -220,6 +220,7 @@ void StorageEngine::Recycle(StorageExecutor *&handle) if (iter != writeUsingList_.end()) { writeUsingList_.remove(handle); if (writeIdleList_.size() >= 1) { + LOGD("[Recycle] delete handle"); delete handle; handle = nullptr; return; @@ -227,6 +228,7 @@ void StorageEngine::Recycle(StorageExecutor *&handle) handle->Reset(); writeIdleList_.push_back(handle); writeCondition_.notify_one(); + idleCondition_.notify_all(); } } else { std::unique_lock lock(readMutex_); @@ -389,6 +391,7 @@ void StorageEngine::CloseExecutor() std::lock_guard lock(writeMutex_); for (auto &item : writeIdleList_) { if (item != nullptr) { + LOGD("[CloseExecutor] delete item"); delete item; item = nullptr; } @@ -449,4 +452,17 @@ bool StorageEngine::IsMigrating() const { return isMigrating_.load(); } + +void StorageEngine::WaitWriteHandleIdle() +{ + std::unique_lock autoLock(idleMutex_); + LOGD("Wait wHandle release id[%s]. write[%zu-%zu-%" PRIu32 "]", DBCommon::TransferStringToHex(identifier_).c_str(), + writeIdleList_.size(), writeUsingList_.size(), engineAttr_.maxWriteNum); + idleCondition_.wait(autoLock, [this]() { + return writeUsingList_.size() == 0; + }); + LOGD("Wait wHandle release finish id[%s]. write[%zu-%zu-%" PRIu32 "]", + DBCommon::TransferStringToHex(identifier_).c_str(), writeIdleList_.size(), writeUsingList_.size(), + engineAttr_.maxWriteNum); +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h index a5fe45ae..36953171 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.h @@ -78,6 +78,8 @@ public: virtual bool IsMigrating() const; + void WaitWriteHandleIdle(); + protected: virtual int CreateNewExecutor(bool isWrite, StorageExecutor *&handle) = 0; @@ -129,6 +131,9 @@ private: std::list readUsingList_; std::list readIdleList_; std::atomic isExistConnection_; + + std::mutex idleMutex_; + std::condition_variable idleCondition_; }; } // namespace DistributedDB #endif // STORAGE_ENGINE_H diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp index c8d711c1..2011404d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp @@ -223,7 +223,7 @@ int StorageProxy::PutCloudSyncData(const std::string &tableName, DownloadData &d } int StorageProxy::CleanCloudData(ClearMode mode, const std::vector &tableNameList, - std::vector &assets) + const RelationalSchemaObject &localSchema, std::vector &assets) { std::shared_lock readLock(storeMutex_); if (store_ == nullptr) { @@ -233,7 +233,7 @@ int StorageProxy::CleanCloudData(ClearMode mode, const std::vector LOGE("the transaction has not been started"); return -E_TRANSACT_STATE; } - return store_->CleanCloudData(mode, tableNameList, assets); + return store_->CleanCloudData(mode, tableNameList, localSchema, assets); } int StorageProxy::ReleaseContinueToken(ContinueToken &continueStmtToken) @@ -275,7 +275,7 @@ int StorageProxy::GetPrimaryColNamesWithAssetsFields(const TableName &tableName, // output parameter should be empty return -E_INVALID_ARGS; } - + std::shared_lock readLock(storeMutex_); if (store_ == nullptr) { return -E_INVALID_DB; @@ -332,4 +332,14 @@ int StorageProxy::FillCloudGidAndAsset(const OpType &opType, const CloudSyncData } return store_->FillCloudGidAndAsset(opType, data); } + +std::string StorageProxy::GetIdentify() const +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + LOGW("[StorageProxy] store is nullptr return default"); + return ""; + } + return store_->GetIdentify(); +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp index e4e207b5..422784cb 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.cpp @@ -318,7 +318,7 @@ int SyncAbleKvDB::EnableManualSync(void) return syncer_.EnableManualSync(); } -int SyncAbleKvDB::GetLocalIdentity(std::string &outTarget) +int SyncAbleKvDB::GetLocalIdentity(std::string &outTarget) const { return syncer_.GetLocalIdentity(outTarget); } @@ -387,6 +387,15 @@ void SyncAbleKvDB::NotifyRemotePushFinishedInner(const std::string &targetId) co int SyncAbleKvDB::SetSyncRetry(bool isRetry) { + IKvDBSyncInterface *syncInterface = GetSyncInterface(); + if (syncInterface == nullptr) { + LOGF("KvDB got null sync interface."); + return -E_INVALID_DB; + } + bool localOnly = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::LOCAL_ONLY, false); + if (localOnly) { + return -E_NOT_SUPPORT; + } if (NeedStartSyncer()) { StartSyncer(); } @@ -430,10 +439,10 @@ bool SyncAbleKvDB::NeedStartSyncer() const int SyncAbleKvDB::GetHashDeviceId(const std::string &clientId, std::string &hashDevId) { - int errCode = E_OK; - if (NeedStartSyncer()) { - errCode = StartSyncer(); + if (!NeedStartSyncer()) { + return syncer_.GetHashDeviceId(clientId, hashDevId); } + int errCode = StartSyncer(); if (errCode != E_OK && errCode != -E_NO_NEED_ACTIVE) { return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h index c5e08092..2b4c079a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sync_able_kvdb.h @@ -114,7 +114,7 @@ protected: // Get the dataItem's append length, the append length = after-serialized-len - original-dataItem-len uint32_t GetAppendedLen() const; - int GetLocalIdentity(std::string &outTarget); + int GetLocalIdentity(std::string &outTarget) const; void TriggerSync(int notifyEvent); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp index 7bc80f9e..21f53179 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.cpp @@ -180,17 +180,25 @@ int CloudDBProxy::Download(const std::string &tableName, const std::string &gid, LOGE("Asset loader has not been set %d", -E_NOT_SET); return -E_NOT_SET; } - return iAssetLoader_->Download(tableName, gid, prefix, assets) == OK ? E_OK : -E_CLOUD_ERROR; + DBStatus status = iAssetLoader_->Download(tableName, gid, prefix, assets); + if (status != OK) { + LOGE("[CloudDBProxy] download asset failed %d", static_cast(status)); + } + return GetInnerErrorCode(status); } int CloudDBProxy::RemoveLocalAssets(const std::vector &assets) { std::shared_lock readLock(assetLoaderMutex_); if (iAssetLoader_ == nullptr) { - LOGE("Asset loader has not been set %d", -E_INVALID_DB); - return -E_INVALID_DB; + LOGE("Asset loader has not been set %d", -E_NOT_SET); + return -E_NOT_SET; } - return iAssetLoader_->RemoveLocalAssets(assets) == OK? E_OK: -E_CLOUD_ERROR; + DBStatus status = iAssetLoader_->RemoveLocalAssets(assets); + if (status != OK) { + LOGE("[CloudDBProxy] remove local asset failed %d", static_cast(status)); + } + return GetInnerErrorCode(status); } int CloudDBProxy::InnerAction(const std::shared_ptr &context, @@ -288,9 +296,7 @@ void CloudDBProxy::InnerActionTask(const std::shared_ptr &co break; } case LOCK: { - std::pair lockStatus = cloudDb->Lock(); - status = (lockStatus.first != OK || lockStatus.second == 0) ? CLOUD_ERROR : OK; - context->MoveInLockStatus(lockStatus); + status = InnerActionLock(context, cloudDb); break; } case UNLOCK: @@ -316,6 +322,23 @@ void CloudDBProxy::InnerActionTask(const std::shared_ptr &co asyncTaskCv_.notify_all(); } +DBStatus CloudDBProxy::InnerActionLock(const std::shared_ptr &context, + const std::shared_ptr &cloudDb) +{ + DBStatus status = OK; + std::pair lockRet; + std::pair lockStatus = cloudDb->Lock(); + if (lockStatus.first != OK) { + status = lockStatus.first; + } else if (lockStatus.second == 0) { + status = CLOUD_ERROR; + } + lockRet.second = lockStatus.second; + lockRet.first = GetInnerErrorCode(status); + context->MoveInLockStatus(lockRet); + return status; +} + int CloudDBProxy::GetInnerErrorCode(DBStatus status) { switch (status) { @@ -329,6 +352,8 @@ int CloudDBProxy::GetInnerErrorCode(DBStatus status) return -E_CLOUD_FULL_RECORDS; case CLOUD_LOCK_ERROR: return -E_CLOUD_LOCK_ERROR; + case CLOUD_ASSET_SPACE_INSUFFICIENT: + return -E_CLOUD_ASSET_SPACE_INSUFFICIENT; default: return -E_CLOUD_ERROR; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h index 957648cd..70baed2e 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h @@ -129,6 +129,9 @@ protected: void InnerActionTask(const std::shared_ptr &context, const std::shared_ptr &cloudDb, InnerActionCode action); + static DBStatus InnerActionLock(const std::shared_ptr &context, + const std::shared_ptr &cloudDb); + static int GetInnerErrorCode(DBStatus status); mutable std::shared_mutex cloudMutex_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp index 2af8c11e..7e067e37 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp @@ -13,23 +13,27 @@ * limitations under the License. */ #include "cloud_force_pull_strategy.h" -#include "db_common.h" -#include "db_errno.h" namespace DistributedDB { -OpType CloudForcePullStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudForcePullStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) { - bool gidEmpty = localInfo.cloudGid.empty(); if (existInLocal) { if (!IsDelete(localInfo) && IsDelete(cloudInfo)) { + (void)deletePrimaryKeySet.insert(localInfo.hashKey); return OpType::DELETE; } else if (IsDelete(cloudInfo)) { return OpType::UPDATE_TIMESTAMP; } else { - return IsDelete(localInfo) ? OpType::INSERT : OpType::UPDATE; + if (IsDelete(localInfo) || deletePrimaryKeySet.find(localInfo.hashKey) != deletePrimaryKeySet.end()) { + return OpType::INSERT; + } else { + return OpType::UPDATE; + } } } else { + bool gidEmpty = localInfo.cloudGid.empty(); if (IsDelete(cloudInfo)) { return gidEmpty ? OpType::NOT_HANDLE : OpType::DELETE; } else { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h index 79db2efd..50cc9676 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.h @@ -19,7 +19,8 @@ namespace DistributedDB { class CloudForcePullStrategy : public CloudSyncStrategy { public: - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) override; bool JudgeUpdateCursor() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp index 1fbac2f6..82e57928 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.cpp @@ -13,33 +13,33 @@ * limitations under the License. */ #include "cloud_force_push_strategy.h" -#include "db_common.h" -#include "db_errno.h" namespace DistributedDB { const std::string cloud_device_name = "cloud"; -OpType CloudForcePushStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudForcePushStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) { + (void)deletePrimaryKeySet; bool isCloudDelete = IsDelete(cloudInfo); - if (existInLocal) { - if (localInfo.cloudGid.empty()) { - // when cloud data is deleted, we think it is different data - return isCloudDelete ? OpType::NOT_HANDLE : OpType::ONLY_UPDATE_GID; - } else { - if (isCloudDelete) { - return OpType::CLEAR_GID; - } - if (localInfo.device == cloud_device_name && localInfo.timestamp == cloudInfo.timestamp) { - return OpType::SET_CLOUD_FORCE_PUSH_FLAG_ONE; - } - if (localInfo.device == cloud_device_name && localInfo.timestamp != cloudInfo.timestamp) { - return OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO; - } - return OpType::NOT_HANDLE; - } - } else { + if (!existInLocal) { return OpType::NOT_HANDLE; } + + if (localInfo.cloudGid.empty()) { + // when cloud data is deleted, we think it is different data + return isCloudDelete ? OpType::NOT_HANDLE : OpType::ONLY_UPDATE_GID; + } + + if (isCloudDelete) { + return OpType::CLEAR_GID; + } + if (localInfo.device == cloud_device_name && localInfo.timestamp == cloudInfo.timestamp) { + return OpType::SET_CLOUD_FORCE_PUSH_FLAG_ONE; + } + if (localInfo.device == cloud_device_name && localInfo.timestamp != cloudInfo.timestamp) { + return OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO; + } + return OpType::NOT_HANDLE; } bool CloudForcePushStrategy::JudgeUpdateCursor() diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h index b7616e67..dfcd5c32 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_push_strategy.h @@ -19,7 +19,8 @@ namespace DistributedDB { class CloudForcePushStrategy : public CloudSyncStrategy { public: - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) override; bool JudgeUpdateCursor() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp index 9b8755fd..0d401313 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp @@ -16,7 +16,8 @@ namespace DistributedDB { -OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) +OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) { bool isCloudDelete = IsDelete(cloudInfo); bool isLocalDelete = IsDelete(localInfo); @@ -37,9 +38,18 @@ OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, LogInfo &localIn return type; } if (isCloudDelete) { - type = isLocalDelete ? OpType::UPDATE_TIMESTAMP : OpType::DELETE; + if (isLocalDelete) { + return OpType::UPDATE_TIMESTAMP; + } else { + (void)deletePrimaryKeySet.insert(localInfo.hashKey); + return OpType::DELETE; + } } else { - type = isLocalDelete ? OpType::INSERT : OpType::UPDATE; + if (isLocalDelete || deletePrimaryKeySet.find(localInfo.hashKey) != deletePrimaryKeySet.end()) { + type = OpType::INSERT; + } else { + type = OpType::UPDATE; + } } return type; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h index 2f07eb5b..7724c173 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.h @@ -23,7 +23,8 @@ public: CloudMergeStrategy() = default; ~CloudMergeStrategy() override = default; - OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) override; + OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) override; bool JudgeUpdateCursor() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h index 2d0fd48b..0c6d5492 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h @@ -27,11 +27,13 @@ public: CloudSyncStrategy() = default; virtual ~CloudSyncStrategy() = default; - virtual OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo) + virtual OpType TagSyncDataStatus(bool existInLocal, LogInfo &localInfo, LogInfo &cloudInfo, + std::set &deletePrimaryKeySet) { (void)existInLocal; (void)localInfo; (void)cloudInfo; + (void)deletePrimaryKeySet; return OpType::NOT_HANDLE; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp new file mode 100644 index 00000000..ee021e4e --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "db_errno.h" +#include "log_print.h" +#include "cloud/cloud_db_constant.h" +#include "cloud/cloud_sync_utils.h" + +namespace DistributedDB { + +int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, + std::vector &cloudPkVals) +{ + if (!cloudPkVals.empty()) { + LOGE("[CloudSyncer] Output paramater should be empty"); + return -E_INVALID_ARGS; + } + if (pkColNames.size() == 1 && pkColNames[0] == CloudDbConstant::ROW_ID_FIELD_NAME) { + // if data don't have primary key, then use rowID as value + cloudPkVals.push_back(dataKey); + return E_OK; + } + for (const auto &pkColName : pkColNames) { + auto iter = datum.find(pkColName); + if (iter == datum.end()) { + LOGE("[CloudSyncer] Cloud data do not contain expected primary field value"); + return -E_CLOUD_ERROR; + } + cloudPkVals.push_back(iter->second); + } + return E_OK; +} + +ChangeType OpTypeToChangeType(OpType strategy) +{ + switch (strategy) { + case OpType::INSERT: + return OP_INSERT; + case OpType::DELETE: + return OP_DELETE; + case OpType::UPDATE: + return OP_UPDATE; + default: + return OP_BUTT; + } +} + + +bool IsCompositeKey(const std::vector &pKColNames) +{ + return (pKColNames.size() > 1); +} + +bool IsNoPrimaryKey(const std::vector &pKColNames) +{ + if (pKColNames.empty()) { + return true; + } + if (pKColNames.size() == 1 && pKColNames[0] == CloudDbConstant::ROW_ID_FIELD_NAME) { + return true; + } + return false; +} + +bool IsSinglePrimaryKey(const std::vector &pKColNames) +{ + if (IsCompositeKey(pKColNames) || IsNoPrimaryKey(pKColNames)) { + return false; + } + return true; +} + +int GetSinglePk(VBucket &datum, const std::vector &pkColNames, int64_t dataKey, Type &pkVal) +{ + std::vector pkVals; + int ret = E_OK; + if (IsSinglePrimaryKey(pkColNames)) { + ret = GetCloudPkVals(datum, pkColNames, dataKey, pkVals); + if (ret != E_OK) { + LOGE("[CloudSyncer] Cannot get single primary key for the datum %d", ret); + return ret; + } + pkVal = pkVals[0]; + if (pkVal.index() == TYPE_INDEX) { + LOGE("[CloudSyncer] Invalid primary key type in TagStatus, it's Nil."); + return -E_INTERNAL_ERROR; + } + } + return E_OK; +} + +void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames) +{ + for (auto item = datum.begin(); item != datum.end();) { + const auto &key = item->first; + if (key != CloudDbConstant::GID_FIELD && + key != CloudDbConstant::CREATE_FIELD && + key != CloudDbConstant::MODIFY_FIELD && + key != CloudDbConstant::DELETE_FIELD && + key != CloudDbConstant::CURSOR_FIELD && + (std::find(pkColNames.begin(), pkColNames.end(), key) == pkColNames.end())) { + item = datum.erase(item); + } else { + item++; + } + } +} +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h new file mode 100644 index 00000000..c05c15d3 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_utils.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CLOUD_SYNC_UTILS_H +#define CLOUD_SYNC_UTILS_H + +#include +#include "cloud/cloud_store_types.h" +#include "icloud_sync_storage_interface.h" + +namespace DistributedDB { +int GetCloudPkVals(const VBucket &datum, const std::vector &pkColNames, int64_t dataKey, + std::vector &cloudPkVals); + +ChangeType OpTypeToChangeType(OpType strategy); + +bool IsCompositeKey(const std::vector &pKColNames); + +bool IsNoPrimaryKey(const std::vector &pKColNames); + +bool IsSinglePrimaryKey(const std::vector &pKColNames); + +int GetSinglePk(VBucket &datum, const std::vector &pkColNames, int64_t dataKey, Type &pkVal); + +void RemoveDataExceptExtendInfo(VBucket &datum, const std::vector &pkColNames); +} +#endif // CLOUD_SYNC_UTILS_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp index 69da43a3..fa7ac63e 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.cpp @@ -19,6 +19,7 @@ #include "cloud/cloud_db_constant.h" #include "cloud/cloud_storage_utils.h" +#include "cloud_sync_utils.h" #include "db_errno.h" #include "cloud/icloud_db.h" #include "kv_store_errno.h" @@ -35,6 +36,7 @@ namespace { const int MAX_HEARTBEAT_FAILED_LIMIT = 2; const int HEARTBEAT_PERIOD = 3; } + CloudSyncer::CloudSyncer(std::shared_ptr storageProxy) : currentTaskId_(INVALID_TASK_ID), storageProxy_(std::move(storageProxy)), @@ -45,6 +47,9 @@ CloudSyncer::CloudSyncer(std::shared_ptr storageProxy) failedHeartBeatCount_(0), syncCallbackCount_(0) { + if (storageProxy_ != nullptr) { + id_ = storageProxy_->GetIdentify(); + } } int CloudSyncer::Sync(const std::vector &devices, SyncMode mode, @@ -90,6 +95,13 @@ int CloudSyncer::SetIAssetLoader(const std::shared_ptr &loader) void CloudSyncer::Close() { closed_ = true; + CloudSyncer::TaskId currentTask; + { + std::lock_guard autoLock(contextLock_); + currentTask = currentContext_.currentTaskId; + } + // mark current task db_closed + SetTaskFailed(currentTask, -E_DB_CLOSED); cloudDB_.Close(); { LOGD("[CloudSyncer] begin wait current task finished"); @@ -199,8 +211,9 @@ void CloudSyncer::ProcessNotifier::NotifyProcess(const CloudTaskInfo &taskInfo, return; // should not happen } RefObject::IncObjRef(syncer); + auto id = syncer->GetIdentify(); syncer->IncSyncCallbackTaskCount(); - int errCode = RuntimeContext::GetInstance()->ScheduleTask([callback, currentProcess, syncer]() { + int errCode = RuntimeContext::GetInstance()->ScheduleQueuedTask(id, [callback, currentProcess, syncer]() { callback(currentProcess); syncer->DecSyncCallbackTaskCount(); RefObject::DecObjRef(syncer); @@ -286,39 +299,46 @@ int CloudSyncer::DoSync(TaskId taskId) int CloudSyncer::DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUpload) { - int errCode = E_OK; - if (needUpload) { - errCode = storageProxy_->StartTransaction(); + if (!needUpload) { + return E_OK; + } + int errCode = storageProxy_->StartTransaction(); + if (errCode != E_OK) { + LOGE("[CloudSyncer] start transaction Failed before doing upload."); + return errCode; + } + for (size_t i = 0; i < taskInfo.table.size(); ++i) { + size_t index = i + 1; + LOGD("[CloudSyncer] try upload table, index: %zu", index); + errCode = CheckTaskIdValid(taskInfo.taskId); if (errCode != E_OK) { - LOGE("[CloudSyncer] start transaction Failed before doing upload."); - return errCode; + LOGE("[CloudSyncer] task is invalid, abort sync"); + break; } - for (size_t i = 0; i < taskInfo.table.size(); ++i) { - LOGD("[CloudSyncer] try upload table, index: %zu", i + 1); - errCode = CheckTaskIdValid(taskInfo.taskId); - if (errCode != E_OK) { - LOGE("[CloudSyncer] task is invalid, abort sync"); - break; - } - { - std::lock_guard autoLock(contextLock_); - currentContext_.tableName = taskInfo.table[i]; - } - errCode = DoUpload(taskInfo.taskId, i == (taskInfo.table.size() - 1u)); - if (errCode != E_OK) { - LOGE("[CloudSyncer] upload failed %d", errCode); - break; - } - errCode = SaveCloudWaterMark(taskInfo.table[i]); - if (errCode != E_OK) { - LOGE("[CloudSyncer] Can not save cloud water mark after uploading %d", errCode); - return errCode; - } + { + std::lock_guard autoLock(contextLock_); + currentContext_.tableName = taskInfo.table[i]; } - if (errCode == E_OK) { - storageProxy_->Commit(); - } else { - storageProxy_->Rollback(); + errCode = DoUpload(taskInfo.taskId, i == (taskInfo.table.size() - 1u)); + if (errCode != E_OK) { + LOGE("[CloudSyncer] upload failed %d", errCode); + break; + } + errCode = SaveCloudWaterMark(taskInfo.table[i]); + if (errCode != E_OK) { + LOGE("[CloudSyncer] Can not save cloud water mark after uploading %d", errCode); + break; + } + } + if (errCode == E_OK) { + int commitErrorCode = storageProxy_->Commit(); + if (commitErrorCode != E_OK) { + LOGE("[CloudSyncer] cannot commit transaction: %d.", commitErrorCode); + } + } else { + int rollBackErrorCode = storageProxy_->Rollback(); + if (rollBackErrorCode != E_OK) { + LOGE("[CloudSyncer] cannot roll back transaction: %d.", rollBackErrorCode); } } return errCode; @@ -328,7 +348,8 @@ int CloudSyncer::DoSyncInner(const CloudTaskInfo &taskInfo, const bool needUploa { int errCode = E_OK; for (size_t i = 0; i < taskInfo.table.size(); ++i) { - LOGD("[CloudSyncer] try download table, index: %zu", i + 1); + size_t index = i + 1; + LOGD("[CloudSyncer] try download table, index: %zu", index); errCode = CheckTaskIdValid(taskInfo.taskId); if (errCode != E_OK) { LOGE("[CloudSyncer] task is invalid, abort sync"); @@ -402,30 +423,8 @@ void CloudSyncer::DoFinished(TaskId taskId, int errCode, const InnerProcessInfo } } -static int GetCloudPkVals(VBucket &datum, const std::vector &pkColNames, int64_t dataKey, - std::vector &cloudPkVals) -{ - if (!cloudPkVals.empty()) { - LOGE("[CloudSyncer] Output paramater should be empty"); - return -E_INVALID_ARGS; - } - if (pkColNames.size() == 1 && pkColNames[0] == CloudDbConstant::ROW_ID_FIELD_NAME) { - // if data don't have primary key, then use rowID as value - cloudPkVals.push_back(dataKey); - return E_OK; - } - for (const auto &pkColName : pkColNames) { - auto iter = datum.find(pkColName); - if (iter == datum.end()) { - LOGE("[CloudSyncer] Cloud data do not contain expected primary field value"); - return -E_CLOUD_ERROR; - } - cloudPkVals.push_back(iter->second); - } - return E_OK; -} - -static int SaveChangedDataByType(VBucket &datum, ChangedData &changedData, DataInfoWithLog &localInfo, ChangeType type) +static int SaveChangedDataByType(VBucket &datum, ChangedData &changedData, const DataInfoWithLog &localInfo, + ChangeType type) { int ret = E_OK; std::vector cloudPkVals; @@ -441,6 +440,11 @@ static int SaveChangedDataByType(VBucket &datum, ChangedData &changedData, DataI return E_OK; } +inline bool EqualInMsLevel(const Timestamp cmp, const Timestamp beCmp) +{ + return cmp / CloudDbConstant::TEN_THOUSAND == beCmp / CloudDbConstant::TEN_THOUSAND; +} + static bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInfo) { // if timeStamp, write timestamp, cloudGid are all the same, @@ -449,13 +453,25 @@ static bool NeedSaveData(const LogInfo &localLogInfo, const LogInfo &cloudLogInf // So, during the strategy policy [i.e. TagSyncDataStatus], the datum was tagged as UPDATE // But we won't notify the datum bool isSame = localLogInfo.timestamp == cloudLogInfo.timestamp && - localLogInfo.wTimestamp == cloudLogInfo.wTimestamp && + EqualInMsLevel(localLogInfo.wTimestamp, cloudLogInfo.wTimestamp) && localLogInfo.cloudGid == cloudLogInfo.cloudGid; return !isSame; } -int CloudSyncer::SaveChangedData(SyncParam ¶m, int dataIndex, DataInfo &dataInfo, - std::vector &InsertDataNoPrimaryKeys) +int CloudSyncer::FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, + size_t &delIdx) +{ + for (std::pair pair : deletedList) { + if (pair.first == hashKey) { + delIdx = pair.second; + return E_OK; + } + } + return E_INTERNAL_ERROR; +} + +int CloudSyncer::SaveChangedData(SyncParam ¶m, int dataIndex, const DataInfo &dataInfo, + std::vector &InsertDataNoPrimaryKeys, std::vector> &deletedList) { // For no primary key situation, if (param.downloadData.opType[dataIndex] == OpType::INSERT && param.changedData.field.size() == 1 && @@ -463,7 +479,29 @@ int CloudSyncer::SaveChangedData(SyncParam ¶m, int dataIndex, DataInfo &data InsertDataNoPrimaryKeys.push_back(dataIndex); return E_OK; } - switch (param.downloadData.opType[dataIndex]) { + OpType opType = param.downloadData.opType[dataIndex]; + Key hashKey = dataInfo.localInfo.logInfo.hashKey; + if (param.deletePrimaryKeySet.find(hashKey) != param.deletePrimaryKeySet.end()) { + if (opType == OpType::INSERT) { + size_t delIdx; + int errCode = FindDeletedListIndex(deletedList, hashKey, delIdx); + if (errCode != E_OK) { + LOGE("[CloudSyncer] FindDeletedListIndex could not find delete item."); + return errCode; + } + param.changedData.primaryData[ChangeType::OP_DELETE].erase( + param.changedData.primaryData[ChangeType::OP_DELETE].begin() + delIdx); + (void)param.dupHashKeySet.insert(hashKey); + opType = OpType::UPDATE; + } else if (opType == OpType::DELETE) { + std::pair pair{hashKey, static_cast( + param.changedData.primaryData[ChangeType::OP_DELETE].size())}; + deletedList.emplace_back(pair); + } else { + LOGW("[CloudSyncer] deletePrimaryKeySet ignore opType %d.", opType); + } + } + switch (opType) { case OpType::INSERT: return SaveChangedDataByType( param.downloadData.data[dataIndex], param.changedData, dataInfo.localInfo, ChangeType::OP_INSERT); @@ -501,8 +539,8 @@ static LogInfo GetCloudLogInfo(VBucket &datum) /** * UpdateChangedData will be used for Insert case, which we can only get rowid after we saved data in db. */ -static void UpdateChangedData( - DownloadData &downloadData, const std::vector &InsertDataNoPrimaryKeys, ChangedData &changedData) +static void UpdateChangedData(DownloadData &downloadData, const std::vector &InsertDataNoPrimaryKeys, + ChangedData &changedData) { if (InsertDataNoPrimaryKeys.empty()) { return; @@ -524,6 +562,8 @@ static void TagAsset(AssetOpType flag, AssetStatus status, Asset &asset, Assets Timestamp timestamp; OS::GetCurrentSysTimeInMicrosecond(timestamp); asset.timestamp = static_cast(timestamp / CloudDbConstant::TEN_THOUSAND); + asset.status = asset.flag == static_cast(AssetOpType::NO_CHANGE) ? + static_cast(AssetStatus::NORMAL) : asset.status; res.push_back(asset); } @@ -562,7 +602,7 @@ static bool IsDataContainField(const std::string &assetFieldName, const VBucket return true; } -// AssetOpType and AssetStatus will be tagged, assets to be changed will be returned +// AssetOpType and AssetStatus will be tagged, assets to be changed will be returned static Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, VBucket &beCoveredData, bool setNormalStatus) { @@ -591,16 +631,16 @@ static Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, return res; } Asset &covered = std::get(coveredData[assetFieldName]); - Assets beCoveredDataInAssets; Asset beCovered; - int ret = CloudStorageUtils::GetValueFromVBucket(assetFieldName, beCoveredData, beCoveredDataInAssets); - if (ret != E_OK) { + if (beCoveredData[assetFieldName].index() == TYPE_INDEX) { // This indicates that asset in cloudData is stored as Asset beCovered = std::get(beCoveredData[assetFieldName]); + } else if (beCoveredData[assetFieldName].index() == TYPE_INDEX) { + // Stored as ASSETS, first element in assets will be the target asset + beCovered = (std::get(beCoveredData[assetFieldName]))[0]; } else { - // This indicates that asset in cloudData is stored as ASSETS - // first element in assets will be the target asset - beCovered = beCoveredDataInAssets[0]; + LOGE("The type of data is neither Asset nor Assets"); + return res; } if (covered.name != beCovered.name) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::INSERT, covered, res); @@ -609,6 +649,9 @@ static Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, } if (covered.hash != beCovered.hash) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::UPDATE, covered, res); + } else { + Assets tmpAssets; + TagAssetWithNormalStatus(true, AssetOpType::NO_CHANGE, covered, tmpAssets); } return res; } @@ -651,7 +694,7 @@ static Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, if (beCoveredAsset.hash != coveredAsset.hash) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::UPDATE, coveredAsset, res); } else { - res.push_back(coveredAsset); + TagAssetWithNormalStatus(setNormalStatus, AssetOpType::NO_CHANGE, coveredAsset, res); } // Erase element which has been handled, remaining element will be set to Insert coveredAssetsIndexMap.erase(it); @@ -737,7 +780,7 @@ std::map CloudSyncer::TagAssetsInSingleRecord(VBucket &cove Assets CloudSyncer::TagAssetsInSingleCol( VBucket &coveredData, VBucket &beCoveredData, const Field &assetField, bool setNormalStatus) -{ +{ // Define a list to store the tagged result Assets assets = {}; switch (assetField.type) { @@ -760,13 +803,13 @@ int CloudSyncer::FillCloudAssets( const std::string &tableName, VBucket &normalAssets, VBucket &failedAssets) { int ret = E_OK; - if (!normalAssets.empty() && normalAssets.size() > 1) { + if (normalAssets.size() > 1) { ret = storageProxy_->FillCloudAssetForDownload(tableName, normalAssets, true); if (ret != E_OK) { return ret; } } - if (!failedAssets.empty() && failedAssets.size() > 1) { + if (failedAssets.size() > 1) { ret = storageProxy_->FillCloudAssetForDownload(tableName, failedAssets, false); if (ret != E_OK) { return ret; @@ -784,48 +827,17 @@ int CloudSyncer::HandleDownloadResult(const std::string &tableName, const std::s failedAssets[CloudDbConstant::GID_FIELD] = gid; for (auto &assetKvPair : DownloadResult) { Assets &assets = assetKvPair.second; - Assets normalAssetsList = {}; - Assets failedAssetsList = {}; - for (Asset &asset : assets) { - // if success, write every attribute of asset into database - if (static_cast(asset.status) == AssetStatus::NORMAL || setAllNormal) { - normalAssetsList.push_back(asset); - continue; - } - // if fail, partially write cloud asset attribute into database - if (static_cast(asset.status) == AssetStatus::ABNORMAL) { - failedAssetsList.push_back(asset); - } - if (static_cast(asset.status) == AssetStatus::DOWNLOADING) { - LOGW("[CloudSyncer] Asset status should not be DOWNLOADING after download operation"); - } - } - if (!normalAssetsList.empty()) { - normalAssets[assetKvPair.first] = normalAssetsList; - } - if (!failedAssetsList.empty()) { - failedAssets[assetKvPair.first] = failedAssetsList; + if (setAllNormal) { + normalAssets[assetKvPair.first] = std::move(assets); + } else { + failedAssets[assetKvPair.first] = std::move(assets); } } return FillCloudAssets(tableName, normalAssets, failedAssets); } -static ChangeType OpTypeToChangeType(OpType strategy) -{ - switch (strategy) { - case OpType::INSERT: - return OP_INSERT; - case OpType::DELETE: - return OP_DELETE; - case OpType::UPDATE: - return OP_UPDATE; - default: - return OP_BUTT; - } -} - int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, DownloadList &downloadList, bool willHandleResult, - ChangedData &changedAssets) + const std::set &dupHashKeySet, ChangedData &changedAssets) { int downloadStatus = E_OK; for (size_t i = 0; i < downloadList.size(); i++) { @@ -834,6 +846,7 @@ int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, DownloadList &dow OpType strategy = std::get<2>(downloadList[i]); // 2 means strategy is the third element in assetsInfo // 3 means assets info [colName, assets] is the forth element in downloadList[i] std::map assets = std::get<3>(downloadList[i]); + Key hashKey = std::get<4>(downloadList[i]); // 4 means hash key std::map downloadAssets(assets); CloudStorageUtils::EraseNoChangeAsset(downloadAssets); // Download data (include deleting) @@ -846,7 +859,11 @@ int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, DownloadList &dow info.downLoadInfo.successCount -= (downloadList.size() - i); return -E_NOT_SET; } - changedAssets.primaryData[OpTypeToChangeType(strategy)].push_back({primaryKey}); + if (dupHashKeySet.find(hashKey) == dupHashKeySet.end()) { + changedAssets.primaryData[OpTypeToChangeType(strategy)].push_back({primaryKey}); + } else if (strategy == OpType::INSERT) { + changedAssets.primaryData[ChangeType::OP_UPDATE].push_back({primaryKey}); + } if (!willHandleResult) { continue; } @@ -876,7 +893,7 @@ int CloudSyncer::CloudDbDownloadAssets(InnerProcessInfo &info, DownloadList &dow } int CloudSyncer::DownloadAssets(InnerProcessInfo &info, const std::vector &pKColNames, - ChangedData &changedAssets) + const std::set &dupHashKeySet, ChangedData &changedAssets) { if (!IsDataContainAssets()) { return E_OK; @@ -898,13 +915,13 @@ int CloudSyncer::DownloadAssets(InnerProcessInfo &info, const std::vector CloudSyncer::GetAssetsFromVBucket(VBucket &data) return assets; } -static bool IsCompositeKey(const std::vector &pKColNames) -{ - return (pKColNames.size() > 1); -} - -static bool IsNoPrimaryKey(const std::vector &pKColNames) -{ - if (pKColNames.empty()) { - return true; - } - if (pKColNames.size() == 1 && pKColNames[0] == CloudDbConstant::ROW_ID_FIELD_NAME) { - return true; - } - return false; -} - -static bool IsSinglePrimaryKey(const std::vector &pKColNames) -{ - if (IsCompositeKey(pKColNames) || IsNoPrimaryKey(pKColNames)) { - return false; - } - return true; -} - -static int GetSinglePk(VBucket &datum, const std::vector &pkColNames, int64_t dataKey, Type &pkVal) -{ - std::vector pkVals; - int ret = E_OK; - if (IsSinglePrimaryKey(pkColNames)) { - ret = GetCloudPkVals(datum, pkColNames, dataKey, pkVals); - if (ret != E_OK) { - LOGE("[CloudSyncer] Cannot get single primary key for the datum %d", ret); - return ret; - } - pkVal = pkVals[0]; - if (pkVal.index() == TYPE_INDEX) { - LOGE("[CloudSyncer] Invalid primary key type in TagStatus, it's Nil."); - return -E_INTERNAL_ERROR; - } - } - return E_OK; -} - int CloudSyncer::TagStatus(bool isExist, SyncParam ¶m, size_t idx, DataInfo &dataInfo, VBucket &localAssetInfo) { OpType strategyOpResult = OpType::NOT_HANDLE; @@ -987,17 +961,22 @@ int CloudSyncer::TagStatus(bool isExist, SyncParam ¶m, size_t idx, DataInfo LOGE("[CloudSyncer] strategy has not been set when tag status, %d.", -E_INTERNAL_ERROR); return -E_INTERNAL_ERROR; } - strategyOpResult = - currentContext_.strategy->TagSyncDataStatus(isExist, dataInfo.localInfo.logInfo, dataInfo.cloudLogInfo); + strategyOpResult = currentContext_.strategy->TagSyncDataStatus(isExist, dataInfo.localInfo.logInfo, + dataInfo.cloudLogInfo, param.deletePrimaryKeySet); } param.downloadData.opType[idx] = strategyOpResult; if (!IsDataContainAssets()) { return E_OK; } - return TagDownloadAssets(idx, param, dataInfo, localAssetInfo); + Key hashKey; + if (isExist) { + hashKey = dataInfo.localInfo.logInfo.hashKey; + } + return TagDownloadAssets(hashKey, idx, param, dataInfo, localAssetInfo); } -int CloudSyncer::TagDownloadAssets(size_t idx, SyncParam ¶m, DataInfo &dataInfo, VBucket &localAssetInfo) +int CloudSyncer::TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam ¶m, DataInfo &dataInfo, + VBucket &localAssetInfo) { Type prefix; int ret = E_OK; @@ -1006,26 +985,26 @@ int CloudSyncer::TagDownloadAssets(size_t idx, SyncParam ¶m, DataInfo &dataI switch (strategy) { case OpType::INSERT: case OpType::UPDATE: - assetsMap = TagAssetsInSingleRecord(param.downloadData.data[idx], localAssetInfo, false); ret = GetSinglePk(param.downloadData.data[idx], param.pkColNames, dataInfo.localInfo.logInfo.dataKey, prefix); if (ret != E_OK) { LOGE("Can not get single primary key while strategy is UPDATE/INSERT in TagDownloadAssets %d", ret); return ret; } + assetsMap = TagAssetsInSingleRecord(param.downloadData.data[idx], localAssetInfo, false); param.assetsDownloadList.downloadList.push_back( - std::make_tuple(dataInfo.cloudLogInfo.cloudGid, prefix, strategy, assetsMap)); + std::make_tuple(dataInfo.cloudLogInfo.cloudGid, prefix, strategy, assetsMap, hashKey)); break; case OpType::DELETE: - assetsMap = TagAssetsInSingleRecord(param.downloadData.data[idx], localAssetInfo, false); ret = GetSinglePk(dataInfo.localInfo.primaryKeys, param.pkColNames, dataInfo.localInfo.logInfo.dataKey, prefix); if (ret != E_OK) { LOGE("Can not get single primary key while strategy is DELETE in TagDownloadAssets %d", ret); return ret; } + assetsMap = TagAssetsInSingleRecord(param.downloadData.data[idx], localAssetInfo, false); param.assetsDownloadList.completeDownloadList.push_back( - std::make_tuple(dataInfo.cloudLogInfo.cloudGid, prefix, strategy, assetsMap)); + std::make_tuple(dataInfo.cloudLogInfo.cloudGid, prefix, strategy, assetsMap, hashKey)); break; case OpType::NOT_HANDLE: case OpType::ONLY_UPDATE_GID: @@ -1047,9 +1026,10 @@ int CloudSyncer::TagDownloadAssets(size_t idx, SyncParam ¶m, DataInfo &dataI return E_OK; } -int CloudSyncer::SaveDatum(SyncParam ¶m, size_t idx, std::vector &InsertDataNoPrimaryKeys) +int CloudSyncer::SaveDatum(SyncParam ¶m, size_t idx, std::vector &InsertDataNoPrimaryKeys, + std::vector> &deletedList) { - int ret = CheckDownloadDatum(param.downloadData.data[idx]); + int ret = PreHandleData(param.downloadData.data[idx], param.pkColNames); if (ret != E_OK) { LOGE("[CloudSyncer] Invalid download data:%d", ret); return ret; @@ -1074,7 +1054,7 @@ int CloudSyncer::SaveDatum(SyncParam ¶m, size_t idx, std::vector &In LOGE("[CloudSyncer] Cannot tag status: %d.", ret); return ret; } - ret = SaveChangedData(param, idx, dataInfo, InsertDataNoPrimaryKeys); + ret = SaveChangedData(param, idx, dataInfo, InsertDataNoPrimaryKeys, deletedList); if (ret != E_OK) { LOGE("[CloudSyncer] Cannot save changed data: %d.", ret); } @@ -1094,9 +1074,13 @@ int CloudSyncer::SaveData(SyncParam ¶m) std::vector InsertDataNoPrimaryKeys; AssetDownloadList assetsDownloadList; param.assetsDownloadList = assetsDownloadList; + param.deletePrimaryKeySet.clear(); + param.dupHashKeySet.clear(); + std::vector> deletedList; for (size_t i = 0; i < param.downloadData.data.size(); i++) { - ret = SaveDatum(param, i, InsertDataNoPrimaryKeys); + ret = SaveDatum(param, i, InsertDataNoPrimaryKeys, deletedList); if (ret != E_OK) { + param.info.downLoadInfo.failCount += param.downloadData.data.size(); LOGE("[CloudSyncer] Cannot save datum due to error code %d", ret); return ret; } @@ -1110,7 +1094,7 @@ int CloudSyncer::SaveData(SyncParam ¶m) ret = storageProxy_->PutCloudSyncData(param.tableName, param.downloadData); if (ret != E_OK) { param.info.downLoadInfo.failCount += param.downloadData.data.size(); - LOGE("[CloudSyncer] Cannot save the data to databse with error code: %d.", ret); + LOGE("[CloudSyncer] Cannot save the data to database with error code: %d.", ret); return ret; } UpdateChangedData(param.downloadData, InsertDataNoPrimaryKeys, param.changedData); @@ -1148,7 +1132,7 @@ int CloudSyncer::PreCheck(CloudSyncer::TaskId &taskId, const TableName &tableNam return E_OK; } -bool CloudSyncer::NeedNotifyChangedData(ChangedData &changedData) +bool CloudSyncer::NeedNotifyChangedData(const ChangedData &changedData) { { std::lock_guard autoLock(contextLock_); @@ -1227,10 +1211,6 @@ int CloudSyncer::SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam &pa ret = SaveData(param); if (ret != E_OK) { LOGE("[CloudSyncer] cannot save data: %d.", ret); - { - std::lock_guard autoLock(contextLock_); - currentContext_.notifier->UpdateProcess(param.info); - } int rollBackErrorCode = storageProxy_->Rollback(); if (rollBackErrorCode != E_OK) { LOGE("[CloudSyncer] cannot roll back transaction: %d.", rollBackErrorCode); @@ -1263,7 +1243,7 @@ int CloudSyncer::SaveDataNotifyProcess(CloudSyncer::TaskId taskId, SyncParam &pa } // Begin dowloading assets ChangedData changedAssets; - ret = DownloadAssets(param.info, param.pkColNames, changedAssets); + ret = DownloadAssets(param.info, param.pkColNames, param.dupHashKeySet, changedAssets); (void)NotifyChangedData(std::move(changedAssets)); if (ret != E_OK) { LOGE("[CloudSyncer] Someting wrong happened during assets downloading due to error %d", ret); @@ -1317,7 +1297,6 @@ int CloudSyncer::DoDownload(CloudSyncer::TaskId taskId) return DoDownloadInner(taskId, param); } - int CloudSyncer::DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m) { // Query data by batch until reaching end and not more data need to be download @@ -1338,6 +1317,9 @@ int CloudSyncer::DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m) queryEnd = true; param.isLastBatch = true; } else if (ret != E_OK) { + std::lock_guard autoLock(contextLock_); + param.info.tableStatus = ProcessStatus::FINISHED; + currentContext_.notifier->UpdateProcess(param.info); return ret; } if (param.downloadData.data.empty()) { @@ -1351,10 +1333,13 @@ int CloudSyncer::DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m) } // Save data in transaction, update cloud water mark, notify process and changed data ret = SaveDataNotifyProcess(taskId, param); - (void)NotifyInDownload(taskId, param); if (ret != E_OK) { + std::lock_guard autoLock(contextLock_); + param.info.tableStatus = ProcessStatus::FINISHED; + currentContext_.notifier->UpdateProcess(param.info); return ret; } + (void)NotifyInDownload(taskId, param); } return E_OK; } @@ -1480,9 +1465,8 @@ int CloudSyncer::PutWaterMarkAfterBatchUpload(const std::string &tableName, Uplo errCode = storageProxy_->PutLocalWaterMark(tableName, uploadParam.localMark); if (errCode != E_OK) { LOGE("[CloudSyncer] Cannot set local water mark while Uploading, %d.", errCode); - return errCode; } - return E_OK; + return errCode; } int CloudSyncer::DoUpload(CloudSyncer::TaskId taskId, bool lastTable) @@ -1680,7 +1664,6 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload ContinueToken continueStmtToken = nullptr; CloudSyncData uploadData(tableName); SetUploadDataFlag(uploadParam.taskId, uploadData); - bool getDataUnfinished = false; int ret = storageProxy_->GetCloudData(tableName, uploadParam.localMark, continueStmtToken, uploadData); if ((ret != E_OK) && (ret != -E_UNFINISHED)) { @@ -1693,12 +1676,13 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload info.tableStatus = ProcessStatus::PROCESSING; info.upLoadInfo.total = static_cast(uploadParam.count); uint32_t batchIndex = 0; + bool getDataUnfinished = false; while (!CheckCloudSyncDataEmpty(uploadData)) { getDataUnfinished = (ret == -E_UNFINISHED); ret = PreProcessBatchUpload(uploadParam.taskId, info, uploadData, uploadParam.localMark); if (ret != E_OK) { - goto RELEASE_EXIT; + break; } info.upLoadInfo.batchIndex = ++batchIndex; @@ -1706,11 +1690,12 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload if (ret != E_OK) { LOGE("[CloudSyncer] Failed to do upload, %d", ret); info.upLoadInfo.failCount = info.upLoadInfo.total - info.upLoadInfo.successCount; + info.tableStatus = ProcessStatus::FINISHED; { std::lock_guard autoLock(contextLock_); currentContext_.notifier->UpdateProcess(info); } - goto RELEASE_EXIT; + break; } uploadData = CloudSyncData(tableName); @@ -1723,18 +1708,17 @@ int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &upload ret = storageProxy_->GetCloudDataNext(continueStmtToken, uploadData); if ((ret != E_OK) && (ret != -E_UNFINISHED)) { LOGE("[CloudSyncer] Failed to get cloud data next when doing upload, %d.", ret); - goto RELEASE_EXIT; + break; } } -RELEASE_EXIT: if (getDataUnfinished) { storageProxy_->ReleaseContinueToken(continueStmtToken); } return ret; } -int CloudSyncer::CheckDownloadDatum(VBucket &datum) +int CloudSyncer::PreHandleData(VBucket &datum, const std::vector &pkColNames) { // type index of field in fields std::vector> filedAndIndex = { @@ -1756,6 +1740,9 @@ int CloudSyncer::CheckDownloadDatum(VBucket &datum) } } + if (std::get(datum[CloudDbConstant::DELETE_FIELD])) { + RemoveDataExceptExtendInfo(datum, pkColNames); + } std::lock_guard autoLock(contextLock_); if (IsDataContainDuplicateAsset(currentContext_.assetFields[currentContext_.tableName], datum)) { return -E_CLOUD_ERROR; @@ -1992,9 +1979,9 @@ void CloudSyncer::HeartBeat(TimerId timerId, TaskId taskId) // heartbeat block twice should finish task now SetTaskFailed(taskId, -E_CLOUD_ERROR); } else { - LOGD("[CloudSyncer] Trigger heartbeat"); - if (cloudDB_.HeartBeat() != E_OK) { - HeartBeatFailed(taskId); + int ret = cloudDB_.HeartBeat(); + if (ret != E_OK) { + HeartBeatFailed(taskId, ret); } else { failedHeartBeatCount_ = 0; } @@ -2015,7 +2002,7 @@ void CloudSyncer::HeartBeat(TimerId timerId, TaskId taskId) } } -void CloudSyncer::HeartBeatFailed(TaskId taskId) +void CloudSyncer::HeartBeatFailed(TaskId taskId, int errCode) { failedHeartBeatCount_++; if (failedHeartBeatCount_ < MAX_HEARTBEAT_FAILED_LIMIT) { @@ -2023,7 +2010,7 @@ void CloudSyncer::HeartBeatFailed(TaskId taskId) } LOGW("[CloudSyncer] heartbeat failed too much times!"); FinishHeartBeatTimer(); - SetTaskFailed(taskId, -E_CLOUD_ERROR); + SetTaskFailed(taskId, errCode); } void CloudSyncer::SetTaskFailed(TaskId taskId, int errCode) @@ -2032,6 +2019,9 @@ void CloudSyncer::SetTaskFailed(TaskId taskId, int errCode) if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { return; } + if (cloudTaskInfos_[taskId].errCode != E_OK) { + return; + } cloudTaskInfos_[taskId].errCode = errCode; } @@ -2149,8 +2139,14 @@ void CloudSyncer::ClearCloudSyncData(CloudSyncData &uploadData) std::vector().swap(uploadData.delData.record); std::vector().swap(uploadData.delData.extend); } +int32_t CloudSyncer::GetCloudSyncTaskCount() +{ + std::lock_guard autoLock(queueLock_); + return taskQueue_.size(); +} -int CloudSyncer::CleanCloudData(ClearMode mode, const std::vector &tableNameList) +int CloudSyncer::CleanCloudData(ClearMode mode, const std::vector &tableNameList, + const RelationalSchemaObject &localSchema) { std::lock_guard lock(syncMutex_); std::string emptyString; @@ -2171,7 +2167,7 @@ int CloudSyncer::CleanCloudData(ClearMode mode, const std::vector & } std::vector assets; - errCode = storageProxy_->CleanCloudData(mode, tableNameList, assets); + errCode = storageProxy_->CleanCloudData(mode, tableNameList, localSchema, assets); if (errCode != E_OK) { LOGE("[CloudSyncer] failed to clean cloud data, %d.", errCode); storageProxy_->Rollback(); @@ -2214,4 +2210,9 @@ void CloudSyncer::UpdateCloudWaterMark(const SyncParam ¶m) currentContext_.cloudWaterMarks[param.info.tableName] = param.cloudWaterMark; } } + +std::string CloudSyncer::GetIdentify() const +{ + return id_; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h index aaf558c5..1ccc43cc 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h @@ -32,7 +32,7 @@ #include "store_observer.h" namespace DistributedDB { -using DownloadList = std::vector>>; +using DownloadList = std::vector, Key>>; class CloudSyncer : public RefObject { public: explicit CloudSyncer(std::shared_ptr storageProxy); @@ -46,7 +46,10 @@ public: int SetIAssetLoader(const std::shared_ptr &loader); - int CleanCloudData(ClearMode mode, const std::vector &tableNameList); + int CleanCloudData(ClearMode mode, const std::vector &tableNameList, + const RelationalSchemaObject &localSchema); + + int32_t GetCloudSyncTaskCount(); void Close(); protected: @@ -73,9 +76,9 @@ protected: }; struct AssetDownloadList { // assets in following list will fill STATUS and timestamp after calling downloading - DownloadList downloadList; + DownloadList downloadList = {}; // assets in following list won't fill STATUS and timestamp after calling downloading - DownloadList completeDownloadList; + DownloadList completeDownloadList = {}; }; struct SyncParam { DownloadData downloadData; @@ -84,6 +87,8 @@ protected: AssetDownloadList assetsDownloadList; CloudWaterMark cloudWaterMark; std::vector pkColNames; + std::set deletePrimaryKeySet; + std::set dupHashKeySet; std::string tableName; bool isLastBatch = false; }; @@ -112,7 +117,7 @@ protected: std::shared_ptr notifier; std::shared_ptr strategy; std::map> assetFields; - // shoulb be cleared after each Download + // should be cleared after each Download AssetDownloadList assetDownloadList; // store GID and assets, using in upload procedure std::map>> assetsInfo; @@ -137,7 +142,7 @@ protected: void DoFinished(TaskId taskId, int errCode, const InnerProcessInfo &processInfo); - virtual int DoDownload(TaskId taskId); + virtual int DoDownload(CloudSyncer::TaskId taskId); int DoDownloadInner(CloudSyncer::TaskId taskId, SyncParam ¶m); @@ -148,7 +153,7 @@ protected: int PreCheck(TaskId &taskId, const TableName &tableName); int DoBatchUpload(CloudSyncData &uploadData, UploadParam &uploadParam, InnerProcessInfo &innerProcessInfo); - + int CheckCloudSyncDataValid(CloudSyncData uploadData, const std::string &tableName, const int64_t &count, TaskId &taskId); @@ -166,7 +171,7 @@ protected: int PutWaterMarkAfterBatchUpload(const std::string &tableName, UploadParam &uploadParam); - virtual int DoUpload(TaskId taskId, bool lastTable); + virtual int DoUpload(CloudSyncer::TaskId taskId, bool lastTable); void SetUploadDataFlag(const TaskId taskId, CloudSyncData& uploadData); @@ -174,7 +179,7 @@ protected: int DoUploadInner(const std::string &tableName, UploadParam &uploadParam); - int CheckDownloadDatum(VBucket &datum); + int PreHandleData(VBucket &datum, const std::vector &pkColNames); int QueryCloudData(const std::string &tableName, CloudWaterMark &cloudWaterMark, DownloadData &downloadData); @@ -200,11 +205,12 @@ protected: void HeartBeat(TimerId timerId, TaskId taskId); - void HeartBeatFailed(TaskId taskId); + void HeartBeatFailed(TaskId taskId, int errCode); void SetTaskFailed(TaskId taskId, int errCode); - - int SaveDatum(SyncParam ¶m, size_t idx, std::vector &InsertDataNoPrimaryKeys); + + int SaveDatum(SyncParam ¶m, size_t idx, std::vector &InsertDataNoPrimaryKeys, + std::vector> &deletedList); int SaveData(SyncParam ¶m); @@ -212,14 +218,17 @@ protected: int SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam ¶m); - int SaveChangedData(SyncParam ¶m, int dataIndex, DataInfo &dataInfo, - std::vector &InsertDataNoPrimaryKeys); + int FindDeletedListIndex(const std::vector> &deletedList, const Key &hashKey, + size_t &delIdx); + + int SaveChangedData(SyncParam ¶m, int dataIndex, const DataInfo &dataInfo, + std::vector &InsertDataNoPrimaryKeys, std::vector> &deletedList); int SaveDataNotifyProcess(CloudSyncer::TaskId taskId, SyncParam ¶m); void NotifyInBatchUpload(const UploadParam &uploadParam, const InnerProcessInfo &innerProcessInfo, bool lastBatch); - bool NeedNotifyChangedData(ChangedData &changedData); + bool NeedNotifyChangedData(const ChangedData &changedData); int NotifyChangedData(ChangedData &&changedData); @@ -233,7 +242,7 @@ protected: int TagStatus(bool isExist, SyncParam ¶m, size_t idx, DataInfo &dataInfo, VBucket &localAssetInfo); - int TagDownloadAssets(size_t idx, SyncParam ¶m, DataInfo &dataInfo, + int TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam ¶m, DataInfo &dataInfo, VBucket &localAssetInfo); void TagUploadAssets(CloudSyncData &uploadData); @@ -244,10 +253,10 @@ protected: std::map &DownloadResult, bool setAllNormal); int DownloadAssets(InnerProcessInfo &info, const std::vector &pKColNames, - ChangedData &changedAssets); + const std::set &dupHashKeySet, ChangedData &changedAssets); int CloudDbDownloadAssets(InnerProcessInfo &info, DownloadList &downloadList, bool willHandleResult, - ChangedData &changedAssets); + const std::set &dupHashKeySet, ChangedData &changedAssets); bool IsDataContainAssets(); @@ -267,6 +276,8 @@ protected: void UpdateCloudWaterMark(const SyncParam ¶m); + std::string GetIdentify() const; + std::mutex queueLock_; TaskId currentTaskId_; std::list taskQueue_; @@ -294,6 +305,8 @@ protected: std::mutex syncCallbackMutex_; std::condition_variable syncCallbackCv_; int32_t syncCallbackCount_; + + std::string id_; }; } #endif // CLOUD_SYNCER_H diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.cpp index 181f476c..180d0cad 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.cpp @@ -121,6 +121,7 @@ void DeviceManager::GetOnlineDevices(std::vector &devices) const devices.assign(devices_.begin(), devices_.end()); } +#ifndef OMIT_MULTI_VER int DeviceManager::SendBroadCast(uint32_t msgId) { if (msgId == LOCAL_DATA_CHANGED) { @@ -160,6 +161,7 @@ int DeviceManager::SendLocalDataChanged() } return E_OK; } +#endif // OMIT_MULTI_VER bool DeviceManager::IsDeviceOnline(const std::string &deviceId) const { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.h index d9cbfaae..4b49636a 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device_manager.h @@ -50,16 +50,20 @@ public: // Get The online devices list. void GetOnlineDevices(std::vector &devices) const; +#ifndef OMIT_MULTI_VER // Send a BroadCast to all online device. int SendBroadCast(uint32_t msgId); +#endif // OMIT_MULTI_VER // Determine if the device is online. bool IsDeviceOnline(const std::string &deviceId) const; private: +#ifndef OMIT_MULTI_VER // Send a local data changed broadcast. int SendLocalDataChanged(); +#endif // OMIT_MULTI_VER std::set devices_; std::function onlineCallback_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp index f9215f1c..64bef321 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/generic_syncer.cpp @@ -1034,6 +1034,11 @@ int GenericSyncer::GetSyncDataSize(const std::string &device, size_t &size) cons LOGE("[Syncer] Syncer is closing, return!"); return -E_BUSY; } + int errCode = static_cast(syncInterface_)->TryHandle(); + if (errCode != E_OK) { + LOGE("[Syncer] syncer is restarting, return!"); + return errCode; + } syncInterface_->IncRefCount(); metadata = metadata_; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/isync_engine.h b/kv_store/frameworks/libs/distributeddb/syncer/src/isync_engine.h index 617ee0ee..4690099c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/isync_engine.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/isync_engine.h @@ -46,8 +46,10 @@ public: // Clear the SyncTarget matched the syncId. virtual void RemoveSyncOperation(int syncId) = 0; +#ifndef OMIT_MULTI_VER // notify other devices data has changed virtual void BroadCastDataChanged() const = 0; +#endif // Get Online devices virtual void GetOnlineDevices(std::vector &devices) const = 0; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.cpp index 1d5753d3..1f5cf00a 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.cpp @@ -496,7 +496,13 @@ int RemoteExecutor::RequestStart(uint32_t sessionId) if (errCode != E_OK) { ReleaseMessageAndPacket(message, packet); LOGE("[RemoteExecutor][RequestStart] set external object failed errCode=%d", errCode); + return errCode; } + return SendRequestMessage(target, message, sessionId); +} + +int RemoteExecutor::SendRequestMessage(const std::string &target, Message *message, uint32_t sessionId) +{ auto communicator = GetAndIncCommunicator(); auto syncInterface = GetAndIncSyncInterface(); if (communicator == nullptr || syncInterface == nullptr) { @@ -510,12 +516,16 @@ int RemoteExecutor::RequestStart(uint32_t sessionId) SendConfig sendConfig; SetSendConfigParam(syncInterface->GetDbProperties(), target, false, REMOTE_EXECUTOR_SEND_TIME_OUT, sendConfig); RefObject::IncObjRef(this); - errCode = communicator->SendMessage(target, message, sendConfig, [this, sessionId](int errCode) { + int errCode = communicator->SendMessage(target, message, sendConfig, [this, sessionId](int errCode) { if (errCode != E_OK) { DoSendFailed(sessionId, errCode); } RefObject::DecObjRef(this); }); + if (errCode != E_OK) { + ReleaseMessageAndPacket(message, nullptr); + RefObject::DecObjRef(this); + } RefObject::DecObjRef(communicator); syncInterface->DecRefCount(); return errCode; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.h b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.h index 8c369574..d2662240 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/remote_executor.h @@ -109,6 +109,7 @@ private: void DoRollBack(uint32_t sessionId); int RequestStart(uint32_t sessionId); + int SendRequestMessage(const std::string &target, Message *message, uint32_t sessionId); int ResponseData(RelationalRowDataSet &&dataSet, const SendMessage &sendMessage, const std::string &device); int ResponseStart(RemoteExecutorAckPacket *packet, uint32_t sessionId, uint32_t sequenceId, diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp index 0954b3b9..0e5371ff 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_data_sync.cpp @@ -837,7 +837,7 @@ int SingleVerDataSync::PullResponseStart(SingleVerSyncTaskContext *context) int errCode = GetMatchData(context, syncData); if (!SingleVerDataSyncUtils::IsGetDataSuccessfully(errCode)) { if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_RELEASE_2_0) { - SendPullResponseDataPkt(errCode, syncData, context); + (void)SendPullResponseDataPkt(errCode, syncData, context); } return errCode; } @@ -931,7 +931,7 @@ int SingleVerDataSync::DoAbilitySyncIfNeed(SingleVerSyncTaskContext *context, co if (isControlMsg) { SendControlAck(context, message, -E_NEED_ABILITY_SYNC, 0); } else { - SendDataAck(context, message, -E_NEED_ABILITY_SYNC, 0); + (void)SendDataAck(context, message, -E_NEED_ABILITY_SYNC, 0); } return -E_NEED_ABILITY_SYNC; } @@ -1108,7 +1108,7 @@ int SingleVerDataSync::SendPullResponseDataPkt(int ackCode, SyncEntry &syncOutDa void SingleVerDataSync::SendFinishedDataAck(SingleVerSyncTaskContext *context, const Message *message) { - SendDataAck(context, message, E_OK, 0); + (void)SendDataAck(context, message, E_OK, 0); } int SingleVerDataSync::SendDataAck(SingleVerSyncTaskContext *context, const Message *message, int32_t recvCode, @@ -1404,7 +1404,10 @@ int32_t SingleVerDataSync::ReSend(SingleVerSyncTaskContext *context, DataSyncReS if (reSendInfo.end > reSendInfo.start) { dataTime.endTime += 1; } - SaveLocalWaterMark(curType, context, dataTime, true); + errCode = SaveLocalWaterMark(curType, context, dataTime, true); + if (errCode != E_OK) { + LOGE("[DataSync][ReSend] SaveLocalWaterMark failed."); + } } return errCode; } @@ -1470,7 +1473,7 @@ int SingleVerDataSync::CheckPermitSendData(int inMode, SingleVerSyncTaskContext } if (mode == SyncModeType::RESPONSE_PULL) { SyncEntry syncData; - SendPullResponseDataPkt(-E_SECURITY_OPTION_CHECK_ERROR, syncData, context); + (void)SendPullResponseDataPkt(-E_SECURITY_OPTION_CHECK_ERROR, syncData, context); return -E_SECURITY_OPTION_CHECK_ERROR; } if (mode == SyncModeType::SUBSCRIBE_QUERY) { @@ -1507,7 +1510,7 @@ bool SingleVerDataSync::WaterMarkErrHandle(SyncType syncType, SingleVerSyncTaskC if (syncType != SyncType::QUERY_SYNC_TYPE && packetLocalMark > peerMark) { LOGI("[DataSync][DataRequestRecv] packetLocalMark=%" PRIu64 ",current=%" PRIu64, packetLocalMark, peerMark); context->SetReceiveWaterMarkErr(true); - SendDataAck(context, message, LOCAL_WATER_MARK_NOT_INIT, 0); + (void)SendDataAck(context, message, LOCAL_WATER_MARK_NOT_INIT, 0); return true; } if (syncType == SyncType::QUERY_SYNC_TYPE && (packetLocalMark > peerMark || packetDeletedMark > deletedMark)) { @@ -1515,7 +1518,7 @@ bool SingleVerDataSync::WaterMarkErrHandle(SyncType syncType, SingleVerSyncTaskC "packetLocalMark=%" PRIu64 ",peerMark=%" PRIu64, packetDeletedMark, deletedMark, packetLocalMark, peerMark); context->SetReceiveWaterMarkErr(true); - SendDataAck(context, message, LOCAL_WATER_MARK_NOT_INIT, 0); + (void)SendDataAck(context, message, LOCAL_WATER_MARK_NOT_INIT, 0); return true; } return false; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp index e075370d..04f57068 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/single_ver_relational_syncer.cpp @@ -187,16 +187,19 @@ int SingleVerRelationalSyncer::SyncConditionCheck(const SyncParma ¶m, const int SingleVerRelationalSyncer::QuerySyncPreCheck(const SyncParma ¶m) const { + if (!param.syncQuery.GetRelationTableNames().empty()) { + LOGE("[SingleVerRelationalSyncer] sync with not support query"); + return -E_NOT_SUPPORT; + } if (!param.isQuerySync) { return E_OK; } if (param.mode == SYNC_MODE_PUSH_PULL) { + LOGE("[SingleVerRelationalSyncer] sync with not support push_pull mode"); return -E_NOT_SUPPORT; } if (param.syncQuery.GetRelationTableName().empty()) { - return -E_NOT_SUPPORT; - } - if (!param.syncQuery.GetRelationTableNames().empty()) { + LOGE("[SingleVerRelationalSyncer] sync with empty table"); return -E_NOT_SUPPORT; } return E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp index ee1c4aaa..1c1b651d 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.cpp @@ -196,12 +196,14 @@ void SyncEngine::RemoveSyncOperation(int syncId) } } +#ifndef OMIT_MULTI_VER void SyncEngine::BroadCastDataChanged() const { if (deviceManager_ != nullptr) { (void)deviceManager_->SendBroadCast(LOCAL_DATA_CHANGED); } } +#endif // OMIT_MULTI_VER void SyncEngine::StartCommunicator() { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h index 7e91d852..9f2d1580 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_engine.h @@ -49,8 +49,10 @@ public: // Clear the SyncTarget matched the syncId. void RemoveSyncOperation(int syncId) override; +#ifndef OMIT_MULTI_VER // notify other devices data has changed void BroadCastDataChanged() const override; +#endif // Get Online devices void GetOnlineDevices(std::vector &devices) const override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp index 77653d96..0b6c5c37 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp @@ -213,6 +213,13 @@ bool SyncOperation::IsAutoControlCmd() const return isAutoSubscribe_; } +void SyncOperation::SetSyncContext(RefObject *context) +{ + RefObject::DecObjRef(context_); + context_ = context; + RefObject::IncObjRef(context); +} + bool SyncOperation::CheckIsAllFinished() const { AutoLock lockGuard(this); @@ -304,13 +311,6 @@ std::string SyncOperation::GetQueryId() const return query_.GetIdentify(); } -void SyncOperation::SetSyncContext(RefObject *context) -{ - RefObject::DecObjRef(context_); - context_ = context; - RefObject::IncObjRef(context); -} - DBStatus SyncOperation::DBStatusTrans(int operationStatus) { static const SyncOperationStatusNode syncOperationStatusNodes[] = { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.cpp index 761b06f6..183435f9 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.cpp @@ -563,12 +563,23 @@ void TimeSync::CommErrHandlerFunc(int errCode, TimeSync *timeSync) void TimeSync::ResetTimer() { - std::lock_guard lock(timeDriverLock_); - RuntimeContext::GetInstance()->RemoveTimer(driverTimerId_, true); + TimerId timerId; + { + std::lock_guard lock(timeDriverLock_); + timerId = driverTimerId_; + driverTimerId_ = 0u; + } + if (timerId == 0u) { + return; + } + RuntimeContext::GetInstance()->RemoveTimer(timerId, true); int errCode = RuntimeContext::GetInstance()->SetTimer( - TIME_SYNC_INTERVAL, driverCallback_, nullptr, driverTimerId_); + TIME_SYNC_INTERVAL, driverCallback_, nullptr, timerId); if (errCode != E_OK) { LOGW("[TimeSync] Reset TimeSync timer failed err :%d", errCode); + } else { + std::lock_guard lock(timeDriverLock_); + driverTimerId_ = timerId; } } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.h b/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.h index 72ddf942..3b235711 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/time_sync.h @@ -59,7 +59,7 @@ private: class TimeSync { public: TimeSync(); - ~TimeSync(); + virtual ~TimeSync(); DISABLE_COPY_ASSIGN_MOVE(TimeSync); @@ -74,7 +74,7 @@ public: int Initialize(ICommunicator *communicator, const std::shared_ptr &metadata, const ISyncInterface *storage, const DeviceID &deviceId); - int SyncStart(const CommErrHandler &handler = nullptr, uint32_t sessionId = 0); // send timesync request + virtual int SyncStart(const CommErrHandler &handler = nullptr, uint32_t sessionId = 0); // send timesync request int AckRecv(const Message *message, uint32_t targetSessionId = 0); diff --git a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn index 617a6a04..9478c2d2 100644 --- a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn @@ -247,6 +247,7 @@ ohos_source_set("src_file") { "../syncer/src/cloud/cloud_force_pull_strategy.cpp", "../syncer/src/cloud/cloud_force_push_strategy.cpp", "../syncer/src/cloud/cloud_merge_strategy.cpp", + "../syncer/src/cloud/cloud_sync_utils.cpp", "../syncer/src/cloud/cloud_syncer.cpp", "../syncer/src/cloud/strategy_factory.cpp", "../syncer/src/commit_history_sync.cpp", @@ -962,6 +963,7 @@ group("distributeddatamgr_fuzztest") { testonly = true deps = [] deps += [ + "fuzztest/cloudsync_fuzzer:fuzztest", "fuzztest/delegate_fuzzer:fuzztest", "fuzztest/fileoper_fuzzer:fuzztest", "fuzztest/importfile_fuzzer:fuzztest", diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/BUILD.gn new file mode 100644 index 00000000..8839d54a --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/BUILD.gn @@ -0,0 +1,116 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/test.gni") +import("../../../distributeddb.gni") + +##############################fuzztest########################################## +ohos_fuzztest("CloudsyncFuzzTest") { + module_out_path = "kv_store/distributeddb" + + include_dirs = [ + "../../../test/fuzztest/common", + "../../../test/unittest/common/common", + "../../../test/unittest/common/syncer", + "../../../test/unittest/common/syncer/cloud", + "../../../test/unittest/common/storage", + "../../../include", + "../../../interfaces/include", + "../../../interfaces/include/cloud", + "../../../interfaces/include/relational", + "../../../interfaces/src", + "../../../interfaces/src/relational", + "../../../storage/include", + "../../../storage/src", + "../../../storage/src/cloud", + "../../../storage/src/multiver", + "../../../storage/src/operation", + "../../../storage/src/sqlite", + "../../../storage/src/sqlite/relational", + "../../../storage/src/upgrader", + "../../../common/include", + "../../../common/include/cloud", + "../../../common/include/relational", + "../../../common/src", + "../../../communicator/include", + "../../../communicator/src", + "../../../syncer/include", + "../../../syncer/src", + "../../../syncer/src/cloud", + ] + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + fuzz_config_file = "../cloudsync_fuzzer" + + sources = distributeddb_src + sources += [ + "../../../test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp", + "../../../test/fuzztest/common/distributeddb_tools_test.cpp", + "../../../test/fuzztest/common/fuzzer_data.cpp", + "../../../test/unittest/common/common/distributeddb_data_generate_unit_test.cpp", + "../../../test/unittest/common/syncer/cloud/virtual_asset_loader.cpp", + "../../../test/unittest/common/syncer/cloud/virtual_cloud_data_translate.cpp", + "../../../test/unittest/common/syncer/cloud/virtual_cloud_db.cpp", + ] + + defines = [ + "SQLITE_ENABLE_SNAPSHOT", + "_LARGEFILE64_SOURCE", + "_FILE_OFFSET_BITS=64", + "SQLITE_HAS_CODEC", + "SQLITE_ENABLE_JSON1", + "USING_HILOG_LOGGER", + "USE_SQLITE_SYMBOLS", + "USING_DB_JSON_EXTRACT_AUTOMATICALLY", + "LOW_LEVEL_MEM_DEV", + "JSONCPP_USE_BUILDER", + "OMIT_FLATBUFFER", + "RELATIONAL_STORE", + "SQLITE_DISTRIBUTE_RELATIONAL", + "SQLITE_EXPORT_SYMBOLS", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", + "OPENSSL_SUPPRESS_DEPRECATED", + ] + + deps = [ + "../../../../distributeddb:distributeddb", + "//third_party/jsoncpp:jsoncpp", + "//third_party/openssl:libcrypto_shared", + "//third_party/sqlite:sqlite", + "//third_party/zlib:shared_libz", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] +} + +############################################################################### + +group("fuzztest") { + testonly = true + deps = [] + deps += [ + # deps file + ":CloudsyncFuzzTest", + ] +} diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp new file mode 100644 index 00000000..bdb8b62e --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cloudsync_fuzzer.h" +#include "cloud_db_types.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_test.h" +#include "log_print.h" +#include "fuzzer_data.h" +#include "relational_store_delegate.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" +#include "virtual_cloud_db.h" + +namespace OHOS { +using namespace DistributedDB; +using namespace DistributedDBTest; + +static const char *g_deviceCloud = "cloud_dev"; +static const char *g_storeId = "STORE_ID"; +static const char *g_dbSuffix = ".db"; +static const char *g_table = "worker1"; +static const char *g_createLocalTableSql = + "CREATE TABLE IF NOT EXISTS worker1(" \ + "name TEXT PRIMARY KEY," \ + "height REAL ," \ + "married BOOLEAN ," \ + "photo BLOB NOT NULL," \ + "assert BLOB," \ + "age INT);"; +class CloudSyncContext { +public: + void FinishAndNotify() + { + { + std::lock_guard autoLock(mutex_); + finished_ = true; + } + cv_.notify_one(); + } + + void WaitForFinish() + { + std::unique_lock uniqueLock(mutex_); + LOGI("begin wait"); + cv_.wait_for(uniqueLock, std::chrono::milliseconds(DBConstant::MAX_TIMEOUT), [this]() { + return finished_; + }); + LOGI("end wait"); + } +private: + std::condition_variable cv_; + std::mutex mutex_; + bool finished_ = false; +}; +class CloudSyncTest { +public: + static void ExecSql(sqlite3 *db, const std::string &sql) + { + if (db == nullptr || sql.empty()) { + return; + } + int errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); + if (errCode != SQLITE_OK) { + LOGE("Execute sql failed. %d err: %s", errCode); + } + } + + static void CreateTable(sqlite3 *&db) + { + ExecSql(db, "PRAGMA journal_mode=WAL;"); + ExecSql(db, g_createLocalTableSql); + } + + static void SetCloudDbSchema(RelationalStoreDelegate *delegate) + { + DataBaseSchema dataBaseSchema; + const std::vector cloudFiled = { + {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, + {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, + {"assert", TYPE_INDEX}, {"age", TYPE_INDEX} + }; + TableSchema tableSchema = { + .name = g_table, + .fields = cloudFiled + }; + dataBaseSchema.tables.push_back(tableSchema); + delegate->SetCloudDbSchema(dataBaseSchema); + delegate->CreateDistributedTable(g_table, CLOUD_COOPERATION); + } + + void SetUp() + { + DistributedDBToolsTest::TestDirInit(testDir_); + storePath_ = testDir_ + "/" + g_storeId + g_dbSuffix; + LOGI("The test db is:%s", testDir_.c_str()); + RuntimeConfig::SetCloudTranslate(std::make_shared()); + LOGD("Test dir is %s", testDir_.c_str()); + db_ = RdbTestUtils::CreateDataBase(storePath_); + if (db_ == nullptr) { + return; + } + CreateTable(db_); + mgr_ = std::make_shared("APP_ID", "USER_ID"); + RelationalStoreDelegate::Option option; + mgr_->OpenStore(storePath_, "STORE_ID", option, delegate_); + virtualCloudDb_ = std::make_shared(); + virtualAssetLoader_ = std::make_shared(); + delegate_->SetCloudDB(virtualCloudDb_); + delegate_->SetIAssetLoader(virtualAssetLoader_); + } + + void TearDown() + { + if (delegate_ != nullptr) { + DBStatus errCode = mgr_->CloseStore(delegate_); + LOGI("delegate close with errCode %d", static_cast(errCode)); + delegate_ = nullptr; + } + if (db_ != nullptr) { + int errCode = sqlite3_close_v2(db_); + LOGI("sqlite close with errCode %d", errCode); + } + virtualCloudDb_ = nullptr; + virtualAssetLoader_ = nullptr; + if (DistributedDBToolsTest::RemoveTestDbFiles(testDir_) != 0) { + LOGE("rm test db files error."); + } + } + + void BlockSync(SyncMode mode = SYNC_MODE_CLOUD_MERGE) + { + Query query = Query::Select().FromTable({ g_table }); + auto context = std::make_shared(); + auto callback = [context](const std::map &onProcess) { + for (const auto &item : onProcess) { + if (item.second.process == ProcessStatus::FINISHED) { + context->FinishAndNotify(); + } + } + }; + DBStatus status = delegate_->Sync({g_deviceCloud}, mode, query, callback, DBConstant::MAX_TIMEOUT); + if (status != OK) { + return; + } + context->WaitForFinish(); + } + + void NormalSync() + { + BlockSync(); + SetCloudDbSchema(delegate_); + BlockSync(); + } + + void RandomModeSync(const uint8_t* data, size_t size) + { + if (size == 0) { + BlockSync(); + return; + } + auto mode = static_cast(data[0]); + LOGI("[RandomModeSync] select mode %d", static_cast(mode)); + BlockSync(mode); + } +private: + std::string testDir_; + std::string storePath_; + sqlite3 *db_ = nullptr; + RelationalStoreDelegate *delegate_ = nullptr; + std::shared_ptr virtualCloudDb_; + std::shared_ptr virtualAssetLoader_; + std::shared_ptr mgr_; +}; +CloudSyncTest *g_cloudSyncTest = nullptr; + +void Setup() +{ + LOGI("Set up"); + g_cloudSyncTest = new(std::nothrow) CloudSyncTest(); + if (g_cloudSyncTest == nullptr) { + return; + } + g_cloudSyncTest->SetUp(); +} + +void TearDown() +{ + LOGI("Tear down"); + g_cloudSyncTest->TearDown(); + if (g_cloudSyncTest != nullptr) { + delete g_cloudSyncTest; + g_cloudSyncTest = nullptr; + } +} + +void CombineTest(const uint8_t* data, size_t size) +{ + if (g_cloudSyncTest == nullptr) { + return; + } + g_cloudSyncTest->NormalSync(); + g_cloudSyncTest->RandomModeSync(data, size); +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + OHOS::Setup(); + OHOS::CombineTest(data, size); + OHOS::TearDown(); + return 0; +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.h b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.h new file mode 100644 index 00000000..b7ddd180 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLOUD_SYNC_FUZZER_H +#define CLOUD_SYNC_FUZZER_H + +#define FUZZ_PROJECT_NAME "CloudSync_fuzzer" + +#endif // CLOUD_SYNC_FUZZER_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/corpus/init b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/corpus/init new file mode 100644 index 00000000..e4ceac1b --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/corpus/init @@ -0,0 +1,14 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FUZZ \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/project.xml b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/project.xml new file mode 100644 index 00000000..798d910c --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 30 + + 4096 + + diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp index 6ab5678c..23edb85e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp @@ -27,10 +27,12 @@ #include #include +#include "cloud_db_constant.h" #include "cloud_db_types.h" #include "db_common.h" #include "db_constant.h" #include "generic_single_ver_kv_entry.h" +#include "time_helper.h" #include "platform_specific.h" #include "runtime_config.h" #include "single_ver_data_packet.h" @@ -1189,4 +1191,27 @@ END: SQLiteUtils::ResetStatement(stmt, true, errCode); return SQLiteUtils::MapSQLiteErrno(errCode); } + +void RelationalTestUtils::GenerateAssetData(const DistributedDB::Asset &sourceAsset, + std::vector &record, std::vector &extend) +{ + VBucket data; + std::vector photo(1, 'v'); + data.insert_or_assign("name", "Local" + std::to_string(0)); + data.insert_or_assign("height", 166.0); // 166.0 is random double value + data.insert_or_assign("married", false); + data.insert_or_assign("age", 13L); + data.insert_or_assign("photo", photo); + Asset asset = sourceAsset; + asset.name = asset.name + std::to_string(0); + data.insert_or_assign("assert", asset); + record.push_back(data); + VBucket log; + Timestamp now = TimeHelper::GetSysCurrentTime(); + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign("#_gid", std::to_string(2)); // 2 is gid + extend.push_back(log); +} } // namespace DistributedDBUnitTest diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h index 1cbf6155..f2f7cd97 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.h @@ -325,6 +325,8 @@ public: static int CheckTableRecords(sqlite3 *db, const std::string &table); static int GetMetaData(sqlite3 *db, const DistributedDB::Key &key, DistributedDB::Value &value); static int SetMetaData(sqlite3 *db, const DistributedDB::Key &key, const DistributedDB::Value &value); + static void GenerateAssetData(const DistributedDB::Asset &sourceAsset, std::vector &record, + std::vector &extend); }; } // namespace DistributedDBUnitTest diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp index 09f932ce..38ec7d38 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp @@ -75,11 +75,12 @@ int AdapterStub::GetLocalIdentity(std::string &outTarget) return E_OK; } -int AdapterStub::SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length) +int AdapterStub::SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length, uint32_t totalLength) { LOGI("[UT][Stub][Send] Send length=%" PRIu32 " to dstTarget=%s begin.", length, dstTarget.c_str()); ApplySendBlock(); + (void)totalLength; { std::lock_guard autoLock(sendBytesMutex_); if (onSendBytes_) { @@ -424,4 +425,4 @@ void AdapterStub::ApplySendBitError(const uint8_t *bytes, uint32_t length) phyHeader->checkSum = HostToNet(CalculateXorSum(bytes + LENGTH_BEFORE_SUM_RANGE, length - LENGTH_BEFORE_SUM_RANGE)); } -} +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h index ac277446..9dc785f0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h @@ -41,7 +41,7 @@ public: uint32_t GetTimeout(const std::string &target) override; int GetLocalIdentity(std::string &outTarget) override; - int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length) override; + int SendBytes(const std::string &dstTarget, const uint8_t *bytes, uint32_t length, uint32_t totalLength) override; int RegBytesReceiveCallback(const BytesReceiveCallback &onReceive, const Finalizer &inOper) override; int RegTargetChangeCallback(const TargetChangeCallback &onChange, const Finalizer &inOper) override; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp index 48c6f49a..faaf5cee 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp @@ -279,38 +279,39 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, SendSchedule001, TestSize.Level2) */ SendTask outTask; SendTaskInfo outTaskInfo; + uint32_t totalLength = 0; // high priority target C - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_C); EXPECT_EQ(outTaskInfo.taskPrio, Priority::HIGH); scheduler.FinalizeLastScheduleTask(); // high priority target A - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_A); EXPECT_EQ(outTaskInfo.taskPrio, Priority::HIGH); scheduler.FinalizeLastScheduleTask(); // normal priority target B - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_B); EXPECT_EQ(outTaskInfo.taskPrio, Priority::NORMAL); scheduler.FinalizeLastScheduleTask(); // normal priority target C - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_C); EXPECT_EQ(outTaskInfo.taskPrio, Priority::NORMAL); scheduler.FinalizeLastScheduleTask(); // low priority target A - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_A); EXPECT_EQ(outTaskInfo.taskPrio, Priority::LOW); scheduler.FinalizeLastScheduleTask(); // low priority target B - errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo); + errCode = scheduler.ScheduleOutSendTask(outTask, outTaskInfo, totalLength); ASSERT_EQ(errCode, E_OK); EXPECT_EQ(outTask.dstTarget, DEVICE_NAME_B); EXPECT_EQ(outTaskInfo.taskPrio, Priority::LOW); @@ -783,13 +784,13 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, NetworkAdapter004, TestSize.Level1) * @tc.expected: step1. adapter send failed */ auto data = std::make_shared(1u); - EXPECT_EQ(adapter->SendBytes("DEVICES_B", nullptr, 1), -E_INVALID_ARGS); - EXPECT_EQ(adapter->SendBytes("DEVICES_B", data.get(), 0), -E_INVALID_ARGS); + EXPECT_EQ(adapter->SendBytes("DEVICES_B", nullptr, 1, 0), -E_INVALID_ARGS); + EXPECT_EQ(adapter->SendBytes("DEVICES_B", data.get(), 0, 0), -E_INVALID_ARGS); /** * @tc.steps: step2. adapter send data with right param * @tc.expected: step2. adapter send ok */ - EXPECT_EQ(adapter->SendBytes("DEVICES_B", data.get(), 1), E_OK); + EXPECT_EQ(adapter->SendBytes("DEVICES_B", data.get(), 1, 0), E_OK); RuntimeContext::GetInstance()->StopTaskPool(); } @@ -911,7 +912,7 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, NetworkAdapter006, TestSize.Level1) return false; }); auto data = std::make_shared(1); - EXPECT_EQ(adapter->SendBytes("", data.get(), 1), -E_PERIPHERAL_INTERFACE_FAIL); + EXPECT_EQ(adapter->SendBytes("", data.get(), 1, 0), -E_PERIPHERAL_INTERFACE_FAIL); RuntimeContext::GetInstance()->StopTaskPool(); EXPECT_EQ(adapter->IsDeviceOnline(""), false); ExtendInfo info; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_import_and_export_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_import_and_export_test.cpp index e8611e2a..5c3a6340 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_import_and_export_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_import_and_export_test.cpp @@ -1257,4 +1257,59 @@ HWTEST_F(DistributedDBInterfacesImportAndExportTest, ImportWithTimeChange001, Te g_kvNbDelegatePtr = nullptr; EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID_1), OK); } + +/** + * @tc.name: abortHandle001 + * @tc.desc: Intercept obtaining new write handles during Import. + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBInterfacesImportAndExportTest, abortHandle001, TestSize.Level1) +{ + std::string singleStoreId = "ExportAbortHandle_001"; + KvStoreNbDelegate::Option option = {true, false, false}; + g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + + /** + * @tc.steps: step1. Init data for export. + */ + std::string str(1024, 'k'); + Value value(str.begin(), str.end()); + for (int i = 0; i < 1000; ++i) { + Key key; + DBCommon::StringToVector(std::to_string(i), key); + g_kvNbDelegatePtr->Put(key, value); + } + + /** + * @tc.steps: step2. Execute the export action. + */ + std::string singleExportFileName = g_exportFileDir + "/UnExportAbortHandle001.$$"; + CipherPassword passwd; + EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK); + + /** + * @tc.steps: step3. Multi threads to occupy write handles. + */ + for (int i = 0; i < 10; ++i) { // 10 is run times + vector threads; + threads.emplace_back(thread([&]() { + g_kvNbDelegatePtr->CheckIntegrity(); + })); + threads.emplace_back(&KvStoreNbDelegate::Import, g_kvNbDelegatePtr, singleExportFileName, passwd); + threads.emplace_back(thread([&i]() { + std::this_thread::sleep_for(std::chrono::milliseconds(i)); + g_kvNbDelegatePtr->CheckIntegrity(); + })); + for (auto &th: threads) { + th.join(); + } + } + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK); + g_junkFilesList.push_back(singleExportFileName); +} #endif // OMIT_ENCRYPT diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp index b3c0f23f..8ee04775 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp @@ -26,6 +26,7 @@ #include "process_system_api_adapter_impl.h" #include "runtime_context.h" #include "sqlite_single_ver_natural_store.h" +#include "storage_engine_manager.h" #include "system_timer.h" #include "kv_virtual_device.h" #include "virtual_communicator_aggregator.h" @@ -202,7 +203,7 @@ namespace { return resultCheck; } -} + class DistributedDBInterfacesNBDelegateTest : public testing::Test { public: static void SetUpTestCase(void); @@ -2469,6 +2470,11 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, LocalStore001, TestSize.Level1) Value actualValue; EXPECT_EQ(openDelegate->Get(key, actualValue), OK); EXPECT_EQ(actualValue, expectValue); + + int pragmaData = 1; + auto input = static_cast(&pragmaData); + EXPECT_EQ(openDelegate->Pragma(SET_SYNC_RETRY, input), NOT_SUPPORT); + EXPECT_EQ(mgr.CloseKvStore(openDelegate), OK); } @@ -2787,4 +2793,64 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, BlockTimer001, TestSize.Level0) }); EXPECT_EQ(g_mgr.DeleteKvStore("BlockTimer001"), OK); g_kvNbDelegatePtr = nullptr; +} + +/** + * @tc.name: MigrateDeadLockTest0011 + * @tc.desc: Test the will not be deadlock in migration. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, MigrateDeadLockTest001, TestSize.Level2) +{ + /** + * @tc.steps:step1. Get the nb delegate. + * @tc.expected: step1. Get results OK and non-null delegate. + */ + KvStoreNbDelegate::Option option = {true, false, false}; + option.secOption = {S3, SECE}; + std::string storeId = "distributed_nb_delegate_test"; + g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + + KvDBProperties property; + property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir); + property.SetStringProp(KvDBProperties::STORE_ID, storeId); + property.SetIntProp(KvDBProperties::SECURITY_LABEL, S3); + property.SetIntProp(KvDBProperties::SECURITY_FLAG, SECE); + + std::string identifier = DBCommon::GenerateIdentifierId(storeId, APP_ID, USER_ID); + property.SetStringProp(KvDBProperties::IDENTIFIER_DATA, DBCommon::TransferHashString(identifier)); + property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE); + + int errCode; + SQLiteSingleVerStorageEngine *storageEngine = + static_cast(StorageEngineManager::GetStorageEngine(property, errCode)); + ASSERT_EQ(errCode, E_OK); + ASSERT_NE(storageEngine, nullptr); + storageEngine->SetEngineState(EngineState::CACHEDB); + + /** + * @tc.steps:step2. create cache db + * @tc.expected: step2. operation ok + */ + std::string cacheDir = g_testDir + "/" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(identifier)) + + "/" + DBConstant::SINGLE_SUB_DIR + "/" + DBConstant::CACHEDB_DIR; + std::string cacheDB = cacheDir + "/" + DBConstant::SINGLE_VER_CACHE_STORE + DBConstant::SQLITE_DB_EXTENSION; + EXPECT_EQ(OS::CreateFileByFileName(cacheDB), E_OK); + + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + + std::this_thread::sleep_for(std::chrono::seconds(3)); // 3 is sleep seconds + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + g_kvNbDelegatePtr = nullptr; + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error!"); + } +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index 20eb746e..369faebd 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -57,6 +57,17 @@ const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_dat "UNIQUE(device, ori_device));" \ "CREATE INDEX key_index ON sync_data(key, flag);"; +const std::string NORMAL_CREATE_NO_UNIQUE = "CREATE TABLE IF NOT EXISTS sync_data(" \ + "key BLOB NOT NULL," \ + "value BLOB," \ + "timestamp INT NOT NULL," \ + "flag INT NOT NULL," \ + "device BLOB," \ + "ori_device BLOB," \ + "hash_key BLOB PRIMARY KEY NOT NULL," \ + "w_timestamp INT);" \ + "CREATE INDEX key_index ON sync_data(key, flag);"; + const std::string SIMPLE_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS t1(a INT, b TEXT)"; const std::string CREATE_TABLE_SQL_NO_PRIMARY_KEY = "CREATE TABLE IF NOT EXISTS sync_data(" \ @@ -71,6 +82,17 @@ const std::string CREATE_TABLE_SQL_NO_PRIMARY_KEY = "CREATE TABLE IF NOT EXISTS "UNIQUE(device, ori_device));" \ "CREATE INDEX key_index ON sync_data (key, flag);"; +const std::string CREATE_TABLE_SQL_NO_PRIMARY_KEY_NO_UNIQUE = "CREATE TABLE IF NOT EXISTS sync_data(" \ + "key BLOB NOT NULL," \ + "value BLOB," \ + "timestamp INT NOT NULL," \ + "flag INT NOT NULL," \ + "device BLOB," \ + "ori_device BLOB," \ + "hash_key BLOB NOT NULL," \ + "w_timestamp INT);" \ + "CREATE INDEX key_index ON sync_data (key, flag);"; + const std::string UNSUPPORTED_FIELD_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test('$.ID' INT, val BLOB);"; const std::string COMPOSITE_PRIMARY_KEY_TABLE_SQL = R"(CREATE TABLE workers ( @@ -86,6 +108,7 @@ const std::string INSERT_SYNC_DATA_SQL = "INSERT OR REPLACE INTO sync_data (key, const std::string INVALID_TABLE_FIELD_SQL = "create table if not exists t1 ('1 = 1; --' int primary key, b blob)"; + void PrepareVirtualDeviceEnv(const std::string &tableName, const std::string &dbPath, const std::vector &remoteDeviceVec) { @@ -164,7 +187,12 @@ void NoramlCreateDistributedTableTest(TableSyncType tableSyncType) sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + if (tableSyncType == DistributedDB::DEVICE_COOPERATION) { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + } else { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); + } + RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A"); EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); @@ -467,7 +495,11 @@ void CreateDistributedTableNonPrimaryKeyTest(TableSyncType tableSyncType) sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_TABLE_SQL_NO_PRIMARY_KEY), SQLITE_OK); + if (tableSyncType == DistributedDB::DEVICE_COOPERATION) { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_TABLE_SQL_NO_PRIMARY_KEY), SQLITE_OK); + } else { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_TABLE_SQL_NO_PRIMARY_KEY_NO_UNIQUE), SQLITE_OK); + } EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); /** @@ -661,7 +693,11 @@ void TableModifyTest(const std::string &modifySql, TableSyncType tableSyncType, sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + if (tableSyncType == DistributedDB::DEVICE_COOPERATION) { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + } else { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); + } RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A"); RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_B"); @@ -790,7 +826,12 @@ void UpgradeDistributedTableTest(TableSyncType tableSyncType) sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + if (tableSyncType == DistributedDB::DEVICE_COOPERATION) { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + } else { + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); + } + RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_A"); RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_B"); RelationalTestUtils::CreateDeviceTable(db, "sync_data", "DEVICE_C"); @@ -887,6 +928,177 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalTableModifyTest005_1, DistributedDB::CLOUD_COOPERATION, OK); } +void CheckTable(TableSyncType tableSyncType, RelationalStoreDelegate *delegate, sqlite3 *db) +{ + /** + * @tc.steps:step4. Create distributed table with a table with "UNIQUE" + * @tc.expected: step4. return OK or NOT_SUPPORT. + */ + std::string tableName4 = "t4"; + std::string createSql = "create table " + tableName4 + "(id int UNIQUE);"; + createSql += "create table t4_1(id int primary key, value text UNIQUE, name int);"; + createSql += "create table t4_2(id int primary key, value text UNIQUE , name int);"; + createSql += "create table t4_3(id int primary key, value text UNIQUE );"; + createSql += "create table t4_4(id int primary key, value text UNIQUE , name int);"; + createSql += "create table t4_5(id int unique);"; + createSql += "create table t4_6(id int primary key, value text UniqUe, name int);"; + createSql += "create table t4_7(id int primary key, uniquekey text , name int);"; + createSql += "create table t4_8(id int , name text, UNIQUE(id, name));"; + createSql += "create table t4_9(id int , name text,UNIQUE(id, name));"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + DBStatus expectCode; + if (tableSyncType == DEVICE_COOPERATION) { + expectCode = OK; + } else { + expectCode = NOT_SUPPORT; + } + EXPECT_EQ(delegate->CreateDistributedTable(tableName4, tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_1", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_2", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_3", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_4", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_5", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_6", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_7", tableSyncType), OK); + EXPECT_EQ(delegate->CreateDistributedTable("t4_8", tableSyncType), expectCode); + EXPECT_EQ(delegate->CreateDistributedTable("t4_9", tableSyncType), expectCode); +} + +void TableConstraintsCheck(TableSyncType tableSyncType, RelationalStoreDelegate *delegate, sqlite3 *db) +{ + /** + * @tc.steps:step1. Create distributed table with a table with "CHECK" key word + * @tc.expected: step1. return NOT_SUPPORT or OK. + */ + std::string tableName1 = "t1"; + std::string createSql = "create table " + tableName1 + "(id int CHECK(id > 5));"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + int expectCode = OK; + if (tableSyncType == DistributedDB::CLOUD_COOPERATION) { + expectCode = NOT_SUPPORT; + } + EXPECT_EQ(delegate->CreateDistributedTable(tableName1, tableSyncType), expectCode); + + /** + * @tc.steps:step2. Create distributed table with a table with foreign key + * @tc.expected: step2. return OK. + */ + std::string tableName2 = "t2"; + createSql = "create table " + tableName2 + "(name text, t1_id int, FOREIGN KEY (t1_id) REFERENCES " + tableName1 + + " (id));"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + EXPECT_EQ(delegate->CreateDistributedTable(tableName2, tableSyncType), OK); + + CheckTable(tableSyncType, delegate, db); + + /** + * @tc.steps:step3. Create distributed table with a table with "WITHOUT ROWID" + * @tc.expected: step3. return NOT_SUPPORT. + */ + std::string tableName3 = "t3"; + createSql = "create table " + tableName3 + "(id int primary key) WITHOUT ROWID;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + EXPECT_EQ(delegate->CreateDistributedTable(tableName3, tableSyncType), NOT_SUPPORT); + + /** + * @tc.steps:step5. Create distributed table with a table with primary key which is real + * @tc.expected: step5. return OK or NOT_SUPPORT. + */ + std::string tableName5 = "t5"; + createSql = "create table " + tableName5 + "(id REAL primary key);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + if (tableSyncType == DEVICE_COOPERATION) { + expectCode = OK; + } else { + expectCode = NOT_SUPPORT; + } + EXPECT_EQ(delegate->CreateDistributedTable(tableName5, tableSyncType), expectCode); + + /** + * @tc.steps:step6. Create distributed table with a table with primary key which is ASSET + * @tc.expected: step6. return OK or NOT_SUPPORT. + */ + std::string tableName6 = "t6"; + createSql = "create table " + tableName6 + "(id ASSET primary key);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + if (tableSyncType == DEVICE_COOPERATION) { + expectCode = OK; + } else { + expectCode = NOT_SUPPORT; + } + EXPECT_EQ(delegate->CreateDistributedTable(tableName6, tableSyncType), expectCode); + + /** + * @tc.steps:step7. Create distributed table with a table with primary key which is ASSETS + * @tc.expected: step7. return OK or NOT_SUPPORT. + */ + std::string tableName7 = "t7"; + createSql = "create table " + tableName7 + "(id assets primary key);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, createSql), SQLITE_OK); + if (tableSyncType == DEVICE_COOPERATION) { + expectCode = OK; + } else { + expectCode = NOT_SUPPORT; + } + EXPECT_EQ(delegate->CreateDistributedTable(tableName7, tableSyncType), expectCode); +} + +void TableConstraintsTest(TableSyncType tableSyncType) +{ + /** + * @tc.steps:step1. Prepare db file + * @tc.expected: step1. Return OK. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + + /** + * @tc.steps:step2. Open store + * @tc.expected: step2. return OK + */ + RelationalStoreDelegate *delegate = nullptr; + DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + + /** + * @tc.steps:step3. check constraints + */ + TableConstraintsCheck(tableSyncType, delegate, db); + + /** + * @tc.steps:step4. Close store + * @tc.expected: step4 Return OK. + */ + EXPECT_EQ(g_mgr.CloseStore(delegate), OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); +} + +/** + * @tc.name: TableConstraintsTest001 + * @tc.desc: Test table constraints when create distributed table with DistributedDB::DEVICE_COOPERATION + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, TableConstraintsTest001, TestSize.Level1) +{ + TableConstraintsTest(DistributedDB::DEVICE_COOPERATION); +} + +/** + * @tc.name: TableConstraintsTest002 + * @tc.desc: Test table constraints when create distributed table with DistributedDB::CLOUD_COOPERATION + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, TableConstraintsTest002, TestSize.Level1) +{ + TableConstraintsTest(DistributedDB::CLOUD_COOPERATION); +} + /** * @tc.name: RelationalRemoveDeviceDataTest001 * @tc.desc: Test remove device data @@ -921,15 +1133,12 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, RelationalRemoveDeviceDataTest00 * @tc.steps:step3. Remove device data * @tc.expected: step3. ok */ - EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), DISTRIBUTED_SCHEMA_NOT_FOUND); - EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), DISTRIBUTED_SCHEMA_NOT_FOUND); - EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data"), DISTRIBUTED_SCHEMA_NOT_FOUND); EXPECT_EQ(delegate->CreateDistributedTable("sync_data"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_B"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_C", "sync_data"), OK); EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_D"), OK); - EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data_A"), DISTRIBUTED_SCHEMA_NOT_FOUND); + EXPECT_EQ(delegate->RemoveDeviceData("DEVICE_A", "sync_data_A"), OK); /** * @tc.steps:step4. Remove device data with invalid args @@ -1504,7 +1713,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest001, T sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); /** @@ -1545,7 +1754,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, T sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); /** @@ -1593,7 +1802,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, T db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); - EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); EXPECT_EQ(delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION), OK); @@ -1609,4 +1818,4 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest002, T EXPECT_EQ(status, OK); delegate = nullptr; } -} \ No newline at end of file +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp index 1deab896..312a64bd 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp @@ -30,6 +30,7 @@ #include "virtual_asset_loader.h" #include "virtual_cloud_data_translate.h" #include "virtual_cloud_db.h" +#include "mock_asset_loader.h" using namespace testing::ext; using namespace DistributedDB; @@ -41,9 +42,10 @@ namespace { const string g_tableName1 = "worker1"; const string g_tableName2 = "worker2"; const string g_tableName3 = "worker3"; + const string g_tableName4 = "worker4"; const string DEVICE_CLOUD = "cloud_dev"; const string DB_SUFFIX = ".db"; - const int64_t g_syncWaitTime = 10; + const int64_t g_syncWaitTime = 60; const int g_arrayHalfSub = 2; int g_syncIndex = 0; string g_testDir; @@ -73,6 +75,7 @@ namespace { "photo BLOB ," \ "asserts BLOB," \ "age INT);"; + const std::string DROP_INTEGER_PRIMARY_KEY_TABLE_SQL = "DROP TABLE " + g_tableName2 + ";"; const std::string CREATE_LOCAL_TABLE_WITHOUT_PRIMARY_KEY_SQL = "CREATE TABLE IF NOT EXISTS " + g_tableName3 + "(" \ "name TEXT," \ @@ -81,6 +84,14 @@ namespace { "photo BLOB NOT NULL," \ "assert BLOB," \ "age INT);"; + const std::string INTEGER_PRIMARY_KEY_TABLE_SQL_WRONG_SYNC_MODE = + "CREATE TABLE IF NOT EXISTS " + g_tableName4 + "(" \ + "id INTEGER PRIMARY KEY," \ + "name TEXT ," \ + "height REAL ," \ + "photo BLOB ," \ + "asserts BLOB," \ + "age INT);"; const std::vector g_cloudFiled1 = { {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, @@ -164,7 +175,7 @@ namespace { EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); SQLiteUtils::ResetStatement(stmt, true, errCode); } - LOGD("insert user record worker1[primary key]:[local%" PRId64 " - cloud%" PRId64 + LOGD("insert user record worker1[primary key]:[Local%" PRId64 " - Local%" PRId64 ") , worker2[primary key]:[%" PRId64 "- %" PRId64")", begin, count, begin, count); } @@ -343,14 +354,11 @@ namespace { SQLiteUtils::ResetStatement(stmt, true, errCode); } - void UpdateLocalAssetsToRepeat(sqlite3 *&db, int64_t rowid) + void UpdateLocalAssets(sqlite3 *&db, Assets &assets, int64_t rowid) { string sql = "UPDATE " + g_tables[1] + " SET asserts = ? where rowid = '" + std::to_string(rowid) + "';"; std::vector assetsBlob; int errCode; - Assets assets; - assets.push_back(g_localAsset); - assets.push_back(g_localAsset); RuntimeContext::GetInstance()->AssetsToBlob(assets, assetsBlob); sqlite3_stmt *stmt = nullptr; ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); @@ -420,6 +428,23 @@ namespace { SQLiteUtils::ResetStatement(stmt, true, errCode); } + void CheckAssetForAssetTest006() + { + VBucket extend; + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); + std::vector data; + g_virtualCloudDb->Query(g_tables[1], extend, data); + for (size_t j = 0; j < data.size(); ++j) { + ASSERT_NE(data[j].find("asserts"), data[j].end()); + ASSERT_TRUE((data[j]["asserts"]).index() == TYPE_INDEX); + Assets &assets = std::get(data[j]["asserts"]); + ASSERT_TRUE(assets.size() > 0); + Asset &asset = assets[0]; + EXPECT_EQ(asset.status, static_cast(AssetStatus::NORMAL)); + EXPECT_EQ(asset.flag, static_cast(AssetOpType::DELETE)); + } + } + void CheckFillAssetForTest10(sqlite3 *&db) { std::string sql = "SELECT assert from " + g_tables[0] + " WHERE rowid in ('27','28','29','30');"; @@ -501,11 +526,11 @@ namespace { return 0; } - void CheckDownloadResult(sqlite3 *&db, std::vector expectCounts) + void CheckDownloadResult(sqlite3 *&db, std::vector expectCounts, std::string keyStr = "Cloud") { for (size_t i = 0; i < g_tables.size(); ++i) { string queryDownload = "select count(*) from " + g_tables[i] + " where name " - + " like 'Cloud%'"; + + " like '" + keyStr + "%'"; EXPECT_EQ(sqlite3_exec(db, queryDownload.c_str(), QueryCountCallback, reinterpret_cast(expectCounts[i]), nullptr), SQLITE_OK); } @@ -523,16 +548,6 @@ namespace { } } - // void CheckLocalTotalNum(sqlite3 *&db, std::vector tableList, std::vector countList) - // { - // int i = 0; - // for (const auto &tableName: tableList) { - // std::string sql = "select count(*) from " + tableName + ";"; - // EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback, - // reinterpret_cast(countList[i]), nullptr), SQLITE_OK); - // i++; - // } - // } void CheckCleanLogNum(sqlite3 *&db, const std::vector tableList, int count) { for (const auto &tableName: tableList) { @@ -608,9 +623,14 @@ namespace { .name = g_tableName3, .fields = g_cloudFiledWithOutPrimaryKey3 }; + TableSchema tableSchema4 = { + .name = g_tableName4, + .fields = g_cloudFiled2 + }; dataBaseSchema.tables.push_back(tableSchema1); dataBaseSchema.tables.push_back(tableSchema2); dataBaseSchema.tables.push_back(tableSchemaWithOutPrimaryKey); + dataBaseSchema.tables.push_back(tableSchema4); } @@ -710,8 +730,7 @@ namespace { } } - void InitProcessForCleanCloudData1(const uint32_t &cloudCount, const uint32_t &localCount, - std::vector &expectProcess) + void InitProcessForCleanCloudData1(const uint32_t &cloudCount, std::vector &expectProcess) { // cloudCount also means data count in one batch expectProcess.clear(); @@ -775,7 +794,7 @@ namespace { FINISHED, {index, cloudCount, cloudCount, 0}, {index, localCount - cloudCount, localCount - cloudCount, 0} }); - for (size_t i = 0; i <= infos.size() / g_arrayHalfSub; ++i) { + for (size_t i = 0; i < infos.size() / g_arrayHalfSub; ++i) { SyncProcess syncProcess; syncProcess.errCode = OK; syncProcess.process = i == infos.size() ? FINISHED : PROCESSING; @@ -819,7 +838,7 @@ namespace { FINISHED, {index, cloudCount, cloudCount, 0}, {0, 0, 0, 0} }); - for (size_t i = 0; i <= infos.size() / g_arrayHalfSub; ++i) { + for (size_t i = 0; i < infos.size() / g_arrayHalfSub; ++i) { SyncProcess syncProcess; syncProcess.errCode = OK; syncProcess.process = i == infos.size() ? FINISHED : PROCESSING; @@ -991,6 +1010,74 @@ namespace { SQLiteUtils::ResetStatement(stmt, true, errCode); } + void UpdateCloudAssetForDownloadAssetTest003() + { + VBucket data; + std::vector photo(1, 'x'); + data.insert_or_assign("name", "Cloud" + std::to_string(0)); + data.insert_or_assign("photo", photo); + data.insert_or_assign("assert", g_cloudAsset); + Timestamp now = TimeHelper::GetSysCurrentTime(); + VBucket log; + std::vector record; + std::vector extend; + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(0)); + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + record.push_back(data); + extend.push_back(log); + ASSERT_EQ(g_virtualCloudDb->BatchUpdate(g_tableName1, std::move(record), extend), DBStatus::OK); + } + + void CheckAssetForDownloadAssetTest003(sqlite3 *&db) + { + string queryDownload = "select assert from " + g_tables[0] + " where rowid = '11';"; + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, queryDownload, stmt), E_OK); + int index = 0; + while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + std::vector blobValue; + ASSERT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, blobValue), E_OK); + Asset asset; + ASSERT_EQ(RuntimeContext::GetInstance()->BlobToAsset(blobValue, asset), E_OK); + EXPECT_EQ(asset.name, g_cloudAsset.name); + EXPECT_EQ(asset.hash, g_cloudAsset.hash); + EXPECT_EQ(asset.status, static_cast(AssetStatus::NORMAL)); + index++; + } + int errCode; + SQLiteUtils::ResetStatement(stmt, true, errCode); + } + + void CheckAssetAfterDownload2(sqlite3 *&db, int64_t localCount) + { + string queryDownload = "select assert from " + g_tables[0] + " where rowid in ("; + for (int64_t i = localCount + 1; i < localCount + localCount; ++i) { + queryDownload += "'" + std::to_string(i) + "',"; + } + queryDownload.pop_back(); + queryDownload += ");"; + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, queryDownload, stmt), E_OK); + int index = 0; + while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + std::vector blobValue; + ASSERT_EQ(SQLiteUtils::GetColumnBlobValue(stmt, 0, blobValue), E_OK); + Asset asset; + ASSERT_EQ(RuntimeContext::GetInstance()->BlobToAsset(blobValue, asset), E_OK); + EXPECT_EQ(asset.version, g_cloudAsset.version); + if (index % 6u == 0) { // 6 is AssetStatus type num, include invalid type + EXPECT_EQ(asset.status, static_cast(AssetStatus::NORMAL)); + } else { + EXPECT_EQ(asset.status, static_cast(AssetStatus::ABNORMAL)); + } + index++; + } + int errCode; + SQLiteUtils::ResetStatement(stmt, true, errCode); + } + void WaitForSyncFinish(SyncProcess &syncProcess, const int64_t &waitTime) { std::unique_lock lock(g_processMutex); @@ -1001,6 +1088,19 @@ namespace { LOGD("-------------------sync end--------------"); } + void callSync(const std::vector &tableNames, SyncMode mode, DBStatus dbStatus) + { + g_syncProcess = {}; + Query query = Query::Select().FromTable(tableNames); + std::vector expectProcess; + CloudSyncStatusCallback callback; + GetCallback(g_syncProcess, callback, expectProcess); + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, mode, query, callback, g_syncWaitTime), dbStatus); + if (dbStatus == DBStatus::OK) { + WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + } + } + void CloseDb() { delete g_observer; @@ -1011,6 +1111,25 @@ namespace { } } + void InitMockAssetLoader(DBStatus &status, int &index) + { + std::shared_ptr assetLoader = make_shared(); + ASSERT_EQ(g_delegate->SetIAssetLoader(assetLoader), DBStatus::OK); + EXPECT_CALL(*assetLoader, Download(testing::_, testing::_, testing::_, testing::_)) + .WillRepeatedly([&status, &index](const std::string &, const std::string &gid, const Type &, + std::map &assets) { + LOGD("Download GID:%s", gid.c_str()); + for (auto &item: assets) { + for (auto &asset: item.second) { + EXPECT_EQ(asset.status, static_cast(AssetStatus::DOWNLOADING)); + LOGD("asset [name]:%s, [status]:%u, [flag]:%u", asset.name.c_str(), asset.status, asset.flag); + asset.status = (index++) % 6u; // 6 is AssetStatus type num, include invalid type + } + } + return status; + }); + } + class DistributedDBCloudInterfacesRelationalSyncTest : public testing::Test { public: static void SetUpTestCase(void); @@ -1219,12 +1338,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest004, TestS for (auto &thread: threads) { thread.join(); } - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, 20); // 20 is wait time + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CloseDb(); } @@ -1272,16 +1386,11 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest006, TestS g_observer->SetExpectedResult(changedDataForTable2); InsertCloudTableRecord(0, cloudCount, paddingSize, false); InsertUserTableRecord(db, 0, cloudCount / g_arrayHalfSub, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); // Set correct cloudDbSchema (correct version) DataBaseSchema correctSchema; GetCloudDbSchema(correctSchema); ASSERT_EQ(g_delegate->SetCloudDbSchema(correctSchema), DBStatus::OK); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); EXPECT_TRUE(g_observer->IsAllChangedDataEq()); g_observer->ClearChangedData(); LOGD("expect download:worker1[primary key]:[cloud0 - cloud20), worker2[primary key]:[10 - 20)"); @@ -1292,15 +1401,13 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest006, TestS // Reset cloudDbSchema (invalid version - null) DataBaseSchema nullSchema; ASSERT_EQ(g_delegate->SetCloudDbSchema(nullSchema), DBStatus::OK); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), - DBStatus::SCHEMA_MISMATCH); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::SCHEMA_MISMATCH); // Reset cloudDbSchema (invalid version - field mismatch) DataBaseSchema invalidSchema; GetInvalidCloudDbSchema(invalidSchema); ASSERT_EQ(g_delegate->SetCloudDbSchema(invalidSchema), DBStatus::OK); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), - DBStatus::SCHEMA_MISMATCH); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::SCHEMA_MISMATCH); CloseDb(); } @@ -1317,12 +1424,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest007, TestS int localCount = 20; InsertUserTableRecord(db, 0, localCount, paddingSize, false); InsertCloudTableRecord(0, localCount / g_arrayHalfSub, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CheckAssetAfterDownload(db, localCount); CheckAllAssetAfterUpload(localCount); @@ -1387,12 +1489,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest0010, Test int localCount = 10; InsertCloudTableRecord(0, cloudCount, paddingSize, false); InsertUserTableRecord(db, 0, localCount, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); int rowid = 27; UpdateAssetForTest(db, AssetOpType::NO_CHANGE, cloudCount, rowid++); @@ -1406,11 +1503,8 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest0010, Test UpdateAssetsForTest(db, AssetOpType::DELETE, id++); UpdateAssetsForTest(db, AssetOpType::UPDATE, id++); - g_syncProcess = {}; - GetCallback(g_syncProcess, callback, expectProcess); LOGD("--------------the second sync-------------"); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CheckFillAssetForTest10(db); CheckFillAssetsForTest10(db); @@ -1459,34 +1553,20 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncTest012, TestS int64_t paddingSize = 10; InsertCloudTableRecord(0, cloudCount, paddingSize, false); InsertUserTableRecord(db, 0, localCount, paddingSize, true); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); InsertCloudTableRecord(localCount + cloudCount, cloudCount, paddingSize, false); InsertUserTableRecord(db, localCount + cloudCount, localCount, paddingSize, true); - g_syncProcess = {}; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); InsertCloudTableRecord(2 * (localCount + cloudCount), cloudCount, paddingSize, false); // 2 is offset InsertUserTableRecord(db, 2 * (localCount + cloudCount), localCount, paddingSize, false); // 2 is offset - g_syncProcess = {}; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); InsertCloudTableRecord(3 * (localCount + cloudCount), cloudCount, paddingSize, true); // 3 is offset InsertUserTableRecord(db, 3 * (localCount + cloudCount), localCount, paddingSize, true); // 3 is offset - g_syncProcess = {}; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CloseDb(); } @@ -1576,7 +1656,6 @@ void TestSyncForStatus(RelationalStoreDelegate *delegate, DBStatus expectStatus) }); } EXPECT_EQ(res, expectStatus); - RuntimeContext::GetInstance()->StopTaskPool(); } /* @@ -1668,12 +1747,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DataNotifier001, TestSi int64_t paddingSize = 10; int localCount = 20; InsertRecordWithoutPk2LocalAndCloud(db, 0, localCount, paddingSize); - Query query = Query::Select().FromTable({g_tableName3}); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync({g_tableName3}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CloseDb(); } @@ -1690,12 +1764,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest001, int localCount = 20; InsertUserTableRecord(db, 0, localCount, paddingSize, false); InsertCloudTableRecord(0, localCount / g_arrayHalfSub, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CheckAssetAfterDownload(db, localCount); CheckAllAssetAfterUpload(localCount); @@ -1725,9 +1794,84 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, MannualNotify001, TestS CloseDb(); } +/** + * @tc.name: CloudProcessNotify001 + * @tc.desc: Test duplicate cloud records. SYNC_MODE_CLOUD_MERGE + * @tc.type: FUNC + * @tc.require: + * @tc.author: liufuchenxing + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudProcessNotify001, TestSize.Level1) +{ + /** + * @tc.steps: step1. table work1 and work2 insert 1 record which name is local0, then sync(). + * @tc.expected: step 1. table work1 and work2 download result is 0. table work1 and work2 upload 1 record. + */ + int64_t paddingSize = 10; + int64_t localCount = 1; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + LOGD("expect download:worker1[primary key]:[], worker2[primary key]:[]"); + CheckDownloadResult(db, {0L, 0L}); // 0 and 0 means the num of downloads from cloud db by worker1 and worker2 + LOGD("expect upload:worker1[primary key]:[local0], worker2[primary key]:[0]"); + CheckCloudTotalCount({1L, 1L}); // 1 and 1 means the total num of worker1 and worker2 from the cloud db + + /** + * @tc.steps: step2. reset data + * @tc.expected: step2. return ok. + */ + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + g_syncProcess = {}; + ASSERT_EQ(g_delegate->SetCloudDB(g_virtualCloudDb), DBStatus::OK); + + /** + * @tc.steps: step3. table work1 delete record which gid is 0 and name is local0 on cloud. + * @tc.expected: step3. return ok. + */ + VBucket idMap; + idMap.insert_or_assign("#_gid", std::to_string(0)); + ASSERT_EQ(g_virtualCloudDb->DeleteByGid(g_tableName1, idMap), DBStatus::OK); + + /** + * @tc.steps: step4. table work1 insert record which gid is 0 and name is local0 on cloud. + * @tc.expected: step4. return ok. + */ + std::vector record1; + std::vector extend1; + RelationalTestUtils::GenerateAssetData(g_cloudAsset, record1, extend1); + ASSERT_EQ(g_virtualCloudDb->BatchInsertWithGid(g_tableName1, std::move(record1), extend1), DBStatus::OK); + + /** + * @tc.steps: step5. sync() and check local data. + * @tc.expected: step5. return ok. + */ + ChangedData changedDataForTable1; + changedDataForTable1.tableName = g_tableName1; + changedDataForTable1.field.push_back(std::string("name")); + changedDataForTable1.primaryData[ChangeType::OP_UPDATE].push_back({"Local" + std::to_string(0)}); + g_observer->SetExpectedResult(changedDataForTable1); + + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + EXPECT_TRUE(g_observer->IsAllChangedDataEq()); + g_observer->ClearChangedData(); + LOGD("expect download:worker1[primary key]:[Local0], worker2[primary key]:[0]"); + // 1 and 1 means the num of downloads from cloud db by worker1 and worker2 + CheckDownloadResult(db, {1L, 1L}, "Local"); + LOGD("expect upload:worker1[primary key]:[local0], worker2[primary key]:[0]"); + CheckCloudTotalCount({1L, 1L}); // 0 and 0 means the total num of worker1 and worker2 from the cloud db + + /** + * @tc.steps: step6. CloseDb(). + * @tc.expected: step6. return ok. + */ + CloseDb(); +} + /* * @tc.name: CleanCloudDataTest001 - * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData + * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData, and invalid mode else. * @tc.type: FUNC * @tc.require: * @tc.author: huangboxin @@ -1741,7 +1885,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest001, InsertUserTableRecord(db, 0, localCount, paddingSize, false); Query query = Query::Select().FromTable(g_tables); std::vector expectProcess; - InitProcessForCleanCloudData1(cloudCount, localCount, expectProcess); + InitProcessForCleanCloudData1(cloudCount, expectProcess); CloudSyncStatusCallback callback; GetCallback(g_syncProcess, callback, expectProcess); ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime), @@ -1751,6 +1895,10 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest001, CheckCloudRecordNum(db, g_tables, {20, 20}); ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_ONLY), DBStatus::OK); CheckCleanLogNum(db, g_tables, 0); + + ASSERT_EQ(g_delegate->RemoveDeviceData(device, ClearMode(BUTT + 1)), DBStatus::INVALID_ARGS); + ASSERT_EQ(g_delegate->RemoveDeviceData(device, ClearMode(-1)), DBStatus::INVALID_ARGS); + CloseDb(); } @@ -1770,7 +1918,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest002, InsertUserTableRecord(db, 0, localCount, paddingSize, false); Query query = Query::Select().FromTable(g_tables); std::vector expectProcess; - InitProcessForCleanCloudData1(cloudCount, localCount, expectProcess); + InitProcessForCleanCloudData1(cloudCount, expectProcess); CloudSyncStatusCallback callback; GetCallback(g_syncProcess, callback, expectProcess); ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime), @@ -1805,7 +1953,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest003, */ Query query = Query::Select().FromTable(g_tables); std::vector expectProcess; - InitProcessForCleanCloudData1(cloudCount, localCount, expectProcess); + InitProcessForCleanCloudData1(cloudCount, expectProcess); CloudSyncStatusCallback callback; GetCallback(g_syncProcess, callback, expectProcess); ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback, g_syncWaitTime), @@ -1816,13 +1964,13 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest003, /** * @tc.steps: step3. insert 10 records into local, so local will has 20 local records and 20 cloud records. */ - InsertUserTableRecord(db, 0, localCount, paddingSize, false); + InsertUserTableRecord(db, 21, localCount, paddingSize, false); // 21 means insert start index /** * @tc.steps: step4. call RemoveDeviceData synchronize with Sync with cloud force push strategy. */ g_syncProcess = {}; std::vector expectProcess2; - InitProcessForCleanCloudData1(cloudCount, localCount, expectProcess2); + InitProcessForCleanCloudData1(cloudCount, expectProcess2); CloudSyncStatusCallback callback2; GetCallback(g_syncProcess, callback2, expectProcess2); std::string device = ""; @@ -1830,7 +1978,6 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest003, std::thread thread1([&]() { ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK); }); - std::condition_variable cv; std::thread thread2([&]() { ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PULL, query, callback2, g_syncWaitTime), DBStatus::OK); @@ -1845,100 +1992,107 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest003, CloseDb(); } +static void InitGetCloudSyncTaskCountTest001(sqlite3 *&db) +{ + int64_t localCount = 20; + int64_t cloudCount = 10; + int64_t paddingSize = 100; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + InsertCloudTableRecord(0, cloudCount, paddingSize, false); +} /* - * @tc.name: CalPrimaryKeyHash001 - * @tc.desc: Test CalcPrimaryKeyHash interface when primary key is string + * @tc.name: GetCloudSyncTaskCountTest001 + * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData concurrently with Sync * @tc.type: FUNC * @tc.require: - * @tc.author: zhuwentao + * @tc.author: huangboxin */ -HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CalPrimaryKeyHash001, TestSize.Level0) +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, GetCloudSyncTaskCountTest001, TestSize.Level0) { - /** - * @tc.steps: step1. local insert one data, primary key is string + InitGetCloudSyncTaskCountTest001(db); + Query query = Query::Select().FromTable(g_tables); + std::mutex dataMutex1, dataMutex2; + std::condition_variable cv1, cv2; + bool finish1 = false, finish2 = false; + /** + * @tc.steps: step1. Call Sync once. + * @tc.expected: OK. + */ + CloudSyncStatusCallback callback1 = [&dataMutex1, &cv1, &finish1]( + const std::map &process) { + std::map syncProcess; + { + std::lock_guard autoLock(dataMutex1); + syncProcess = process; + if (syncProcess[DEVICE_CLOUD].process == FINISHED) { + finish1 = true; + } + } + cv1.notify_one(); + }; + /** + * @tc.steps: step2. Call Sync twice. * @tc.expected: OK. */ - std::string photo(1u, 'v'); - std::string name = "Local0"; - std::map primaryKey = {{"name", name}}; - string sql = "INSERT OR REPLACE INTO " + g_tableName1 - + " (name, height, married, photo, age) VALUES ('Local" + std::to_string(0) + - "', '175.8', '0', '" + photo + "', '18');"; - EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); - std::vector result = RelationalStoreManager::CalcPrimaryKeyHash(primaryKey); - EXPECT_NE(result.size(), 0u); - std::string logTableName = RelationalStoreManager::GetDistributedLogTableName(g_tableName1); - /** - * @tc.steps: step1. query timestamp use hashKey + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback1, g_syncWaitTime), DBStatus::OK); + + CloudSyncStatusCallback callback2 = [&dataMutex2, &cv2, &finish2]( + const std::map &process) { + std::map syncProcess; + { + std::lock_guard autoLock(dataMutex2); + syncProcess = process; + if (syncProcess[DEVICE_CLOUD].process == FINISHED) { + finish2 = true; + } + } + cv2.notify_one(); + }; + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback2, g_syncWaitTime), DBStatus::OK); + /** + * @tc.steps: step3. Call Get Cloud Sync Task Count + * @tc.expected: OK. + */ + EXPECT_EQ(g_delegate->GetCloudSyncTaskCount(), 2); // 2 is task count + /** + * @tc.steps: step3. Wait For Sync Task Finished * @tc.expected: OK. */ - std::string querysql = "select timestamp/10000 from " + logTableName + " where hash_key=?"; - sqlite3_stmt *statement = nullptr; - int errCode = SQLiteUtils::GetStatement(db, querysql, statement); - EXPECT_EQ(errCode, E_OK); - errCode = SQLiteUtils::BindBlobToStatement(statement, 1, result); // 1 means hashkey index - if (errCode != E_OK) { - SQLiteUtils::ResetStatement(statement, true, errCode); - return; + { + std::unique_lock uniqueLock(dataMutex1); + cv1.wait(uniqueLock, [&finish1] { + return finish1; + }); } - errCode = SQLiteUtils::StepWithRetry(statement, false); - if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - Timestamp timestamp = static_cast(sqlite3_column_int64(statement, 0)); - LOGD("get timestamp = %" PRIu64, timestamp); - errCode = E_OK; - } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - errCode = -E_NOT_FOUND; + { + std::unique_lock uniqueLock(dataMutex2); + cv2.wait(uniqueLock, [&finish2] { + return finish2; + }); } - EXPECT_EQ(errCode, E_OK); - SQLiteUtils::ResetStatement(statement, true, errCode); + RuntimeContext::GetInstance()->StopTaskPool(); CloseDb(); } /* - * @tc.name: CalPrimaryKeyHash002 - * @tc.desc: Test CalcPrimaryKeyHash interface when primary key is int + * @tc.name: CleanCloudDataTest004 + * @tc.desc: Test RemoveDeviceData when cloudSchema doesn't have local table * @tc.type: FUNC * @tc.require: - * @tc.author: zhuwentao + * @tc.author: huangboxin */ -HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CalPrimaryKeyHash002, TestSize.Level0) +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CleanCloudDataTest004, TestSize.Level0) { - /** - * @tc.steps: step1. local insert one data, primary key is int - * @tc.expected: OK. - */ - int64_t id = 1; - std::map primaryKey = {{"id", id}}; - std::string sql = "INSERT OR REPLACE INTO " + g_tableName2 - + " (id, name, height) VALUES ('" + '1' + "', 'Local" - + std::to_string(0) + "', '155.10');"; - EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); - std::vector result = RelationalStoreManager::CalcPrimaryKeyHash(primaryKey); - EXPECT_NE(result.size(), 0u); - std::string logTableName = RelationalStoreManager::GetDistributedLogTableName(g_tableName2); - /** - * @tc.steps: step1. query timestamp use hashKey - * @tc.expected: OK. - */ - std::string querysql = "select timestamp/10000 from " + logTableName + " where hash_key=?"; - sqlite3_stmt *statement = nullptr; - int errCode = SQLiteUtils::GetStatement(db, querysql, statement); - EXPECT_EQ(errCode, E_OK); - errCode = SQLiteUtils::BindBlobToStatement(statement, 1, result); // 1 means hashkey index - if (errCode != E_OK) { - SQLiteUtils::ResetStatement(statement, true, errCode); - return; - } - errCode = SQLiteUtils::StepWithRetry(statement, false); - if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - Timestamp timestamp = static_cast(sqlite3_column_int64(statement, 0)); - LOGD("get timestamp = %" PRIu64, timestamp); - errCode = E_OK; - } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - errCode = -E_NOT_FOUND; - } - EXPECT_EQ(errCode, E_OK); - SQLiteUtils::ResetStatement(statement, true, errCode); + DataBaseSchema dataBaseSchema; + TableSchema tableSchema1 = { + .name = "table_not_existed", + .fields = g_cloudFiled1 + }; + dataBaseSchema.tables.push_back(tableSchema1); + GetCloudDbSchema(dataBaseSchema); + ASSERT_EQ(g_delegate->SetCloudDbSchema(dataBaseSchema), DBStatus::OK); + std::string device = ""; + ASSERT_EQ(g_delegate->RemoveDeviceData(device, FLAG_AND_DATA), DBStatus::OK); CloseDb(); } @@ -1956,13 +2110,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest002, int cloudCount = 3; InsertCloudTableRecord(0, cloudCount, paddingSize, true); InsertUserTableRecord(db, 0, localCount, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_FORCE_PUSH, query, callback, g_syncWaitTime), - DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_FORCE_PUSH, DBStatus::OK); CloseDb(); } @@ -1980,7 +2128,10 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest003, int cloudCount = 3; InsertCloudTableRecord(0, cloudCount, paddingSize, true); InsertUserTableRecord(db, 0, localCount, paddingSize, false); - UpdateLocalAssetsToRepeat(db, 1); + Assets assets; + assets.push_back(g_localAsset); + assets.push_back(g_localAsset); + UpdateLocalAssets(db, assets, 1); Query query = Query::Select().FromTable(g_tables); std::vector expectProcess; CloudSyncStatusCallback callback = [](const std::map &process) { @@ -2017,13 +2168,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest004, int cloudCount = 3; InsertUserTableRecord(db, 0, localCount, paddingSize, false); InsertCloudTableRecord(0, cloudCount, paddingSize, false); - Query query = Query::Select().FromTable(g_tables); - std::vector expectProcess; - CloudSyncStatusCallback callback; - GetCallback(g_syncProcess, callback, expectProcess); - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), - DBStatus::OK); - WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); UpdateDiffType(localCount); g_syncProcess = {}; @@ -2034,7 +2179,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest004, g_processCondition.notify_one(); } }; - + Query query = Query::Select().FromTable(g_tables); ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback1, g_syncWaitTime), DBStatus::OK); { @@ -2047,5 +2192,425 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest004, CheckDiffTypeAsset(db); CloseDb(); } + +/* + * @tc.name: CloudSyncAssetTest005 + * @tc.desc: Test erase all no change Asset + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. Construct local data with asset names and hashes consistent with the cloud + * @tc.expected: step1. return ok. + */ + int64_t paddingSize = 10; + int localCount = 3; + int cloudCount = 3; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + Assets assets; + for (int64_t j = 0; j < cloudCount; j++) { + Asset asset = g_cloudAsset; + asset.name = g_cloudAsset.name + std::to_string(j); + assets.push_back(asset); + } + UpdateLocalAssets(db, assets, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(cloudCount)); + + /** + * @tc.steps:step2. Construct cloud data + * @tc.expected: step2. return ok. + */ + InsertCloudTableRecord(0, cloudCount, paddingSize, false); + + /** + * @tc.steps:step3. sync, expect EraseNoChangeAsset to erase all Nochange assets + * @tc.expected: step3. return ok. + */ + Query query = Query::Select().FromTable(g_tables); + std::vector expectProcess; + CloudSyncStatusCallback callback = [](const std::map &process) { + ASSERT_EQ(process.size(), 1u); + g_syncProcess = std::move(process.begin()->second); + + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), + DBStatus::OK); + { + std::unique_lock lock(g_processMutex); + g_processCondition.wait(lock, []() { + return g_syncProcess.process == FINISHED; + }); + ASSERT_EQ(g_syncProcess.errCode, DBStatus::OK); + } + CloseDb(); +} + +/* + * @tc.name: CloudSyncAssetTest006 + * @tc.desc: Test upload new data without assets + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest006, TestSize.Level0) +{ + /** + * @tc.steps:step1. Construct local data with NULL asset and the local count is greater than the cloud + * @tc.expected: step1. return ok. + */ + int64_t paddingSize = 10; + int localCount = 6; + int cloudCount = 3; + InsertUserTableRecord(db, 0, localCount, paddingSize, true); + std::this_thread::sleep_for(std::chrono::milliseconds(cloudCount)); + InsertCloudTableRecord(0, cloudCount, paddingSize, false); + + /** + * @tc.steps:step2. sync, upload new data without assets, + * @tc.expected: step2. return ok. + */ + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + CloseDb(); +} + +/* + * @tc.name: CloudSyncAssetTest007 + * @tc.desc: for expilictly set not-change assets. If an asset is deleted, and its hash is not set to empty, it will be + * regarded as NO-CHANGE, rather than delete + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest007, TestSize.Level0) +{ + /** + * @tc.steps:step1. local asset contain an asset which has a corresponding asset in cloud + * @tc.expected: step1. return ok. + */ + int64_t paddingSize = 10; + int localCount = 1; + int cloudCount = 1; + InsertCloudTableRecord(0, cloudCount, paddingSize, false); + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + /** + * @tc.steps:step2. local asset is set to delete, but hash is not set to empty + * @tc.expected: step2. return ok. + */ + Assets assets; + for (int64_t j = 0; j < cloudCount; j++) { + Asset asset = g_cloudAsset; + asset.name = g_cloudAsset.name + std::to_string(j); + asset.status = static_cast(AssetStatus::DELETE); + assets.push_back(asset); + } + UpdateLocalAssets(db, assets, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(cloudCount)); + /** + * @tc.steps:step3. Do sync + * @tc.expected: step3. return ok. + */ + Query query = Query::Select().FromTable(g_tables); + std::vector expectProcess; + CloudSyncStatusCallback callback = [](const std::map &process) { + ASSERT_EQ(process.size(), 1u); + g_syncProcess = std::move(process.begin()->second); + + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), + DBStatus::OK); + { + std::unique_lock lock(g_processMutex); + g_processCondition.wait(lock, []() { + return g_syncProcess.process == FINISHED; + }); + ASSERT_EQ(g_syncProcess.errCode, DBStatus::OK); + } + /** + * @tc.steps:step4. Check result. Cloud db should not contain asset. + * @tc.expected: step4. return ok. + */ + CheckAssetForAssetTest006(); + CloseDb(); +} + + +/** + * @tc.name: DownloadAssetTest001 + * @tc.desc: Test the sync of different Asset status out of parameters when the download is successful + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DownloadAssetTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Set different status out of parameters, and the code returns OK + * @tc.expected: step1. return ok. + */ + DBStatus expectStatus = DBStatus::OK; + int index = 0; + InitMockAssetLoader(expectStatus, index); + + /** + * @tc.steps:step2. init download data + * @tc.expected: step2. return ok. + */ + int64_t paddingSize = 1; + int localCount = 120; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + InsertCloudTableRecord(0, localCount / g_arrayHalfSub, paddingSize, false); + + /** + * @tc.steps:step3. sync + * @tc.expected: step3. return ok. + */ + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step4. Expect all states to be normal + * @tc.expected: step4. return ok. + */ + CheckAssetAfterDownload(db, localCount); + CloseDb(); +} + +/* + * @tc.name: CloudSyncAssetTest008 + * @tc.desc: sync failed with download asset + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudSyncAssetTest008, TestSize.Level0) +{ + /** + * @tc.steps:step1. prepare asset data + */ + int64_t paddingSize = 10; + int localCount = 1; + int cloudCount = 1; + InsertCloudTableRecord(0, cloudCount, paddingSize, false); + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + /** + * @tc.steps:step2. set download asset status failed + */ + g_virtualAssetLoader->SetDownloadStatus(CLOUD_ASSET_SPACE_INSUFFICIENT); + Query query = Query::Select().FromTable(g_tables); + std::vector expectProcess; + CloudSyncStatusCallback callback = [](const std::map &process) { + for (const auto &item: process) { + g_syncProcess = item.second; + } + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + /** + * @tc.steps:step3. sync and wait sync finished. + * @tc.expected: step3. sync return CLOUD_ASSET_SPACE_INSUFFICIENT. + */ + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), + DBStatus::OK); + { + std::unique_lock lock(g_processMutex); + g_processCondition.wait(lock, []() { + return g_syncProcess.process == FINISHED; + }); + ASSERT_EQ(g_syncProcess.errCode, DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT); + } + /** + * @tc.steps:step4. clear data. + */ + g_virtualAssetLoader->SetDownloadStatus(OK); + CloseDb(); +} + +/** + * @tc.name: DownloadAssetTest002 + * @tc.desc: Test the sync of different Asset status out of parameters when the download is failed + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DownloadAssetTest002, TestSize.Level0) +{ + /** + * @tc.steps:step1. Set different status out of parameters, and the code returns CLOUD_ERROR + * @tc.expected: step1. return ok. + */ + DBStatus expectStatus = DBStatus::CLOUD_ERROR; + int index = 0; + InitMockAssetLoader(expectStatus, index); + int64_t paddingSize = 1; + int localCount = 100; + + /** + * @tc.steps:step2. init download data + * @tc.expected: step2. return ok. + */ + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + InsertCloudTableRecord(0, localCount, paddingSize, false); + + /** + * @tc.steps:step3. sync + * @tc.expected: step3. return ok. + */ + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step4. Those status that are not normal are all be abnormal after sync. + * @tc.expected: step4. return ok. + */ + CheckAssetAfterDownload2(db, localCount); + CloseDb(); +} + +/** + * @tc.name: DownloadAssetTest003 + * @tc.desc: Init different asset name between local and cloud, then sync to test download + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DownloadAssetTest003, TestSize.Level0) +{ + /** + * @tc.steps:step1. Init data and sync + * @tc.expected: step1. return ok. + */ + int64_t paddingSize = 1; + int localCount = 10; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + InsertCloudTableRecord(0, localCount, paddingSize, false); + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step2. update cloud Asset where gid = 0 + * @tc.expected: step2. return ok. + */ + UpdateCloudAssetForDownloadAssetTest003(); + + /** + * @tc.steps:step3. sync again + * @tc.expected: step3. return ok. + */ + callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step4. check asset after download where gid = 0 + * @tc.expected: step4. return ok. + */ + CheckAssetForDownloadAssetTest003(db); + CloseDb(); +} + +/** + * @tc.name: DownloadAssetTest004 + * @tc.desc: Test total count, fail count and success count when drop table + * @tc.type: FUNC + * @tc.require: + * @tc.author: liufuchenxing + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, DownloadAssetTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. Init data and sync + * @tc.expected: step1. return ok. + */ + int64_t paddingSize = 1; + int count = 10; + InsertUserTableRecord(db, 0, count, paddingSize, false); + g_syncProcess = {}; + CloudSyncStatusCallback callback = [](const std::map &process) { + for (const auto &item : process) { + g_syncProcess = item.second; + } + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + } + }; + Query query = Query::Select().FromTable(g_tables); + EXPECT_EQ(g_delegate->Sync({ DEVICE_CLOUD }, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); + WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + + /** + * @tc.steps:step2. drop table work2. sync failed, check total, success and fail count. + * @tc.expected: step2. total = 20, success=0, fail=20 + */ + g_syncProcess = {}; + InsertCloudTableRecord(0, count, paddingSize, false); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, DROP_INTEGER_PRIMARY_KEY_TABLE_SQL), DBStatus::OK); + EXPECT_EQ(g_delegate->Sync({ DEVICE_CLOUD }, SYNC_MODE_CLOUD_MERGE, query, callback, g_syncWaitTime), DBStatus::OK); + WaitForSyncFinish(g_syncProcess, g_syncWaitTime); + EXPECT_EQ(g_syncProcess.errCode, DBStatus::DB_ERROR); + uint32_t expectTotalCnt = 20u; + EXPECT_NE(g_syncProcess.tableProcess.find(g_tableName2), g_syncProcess.tableProcess.end()); + EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.batchIndex, 1u); + EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.total, expectTotalCnt); + EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.successCount, 0u); + EXPECT_EQ(g_syncProcess.tableProcess[g_tableName2].downLoadInfo.failCount, expectTotalCnt); + + /** + * @tc.steps:step3. close db. + * @tc.expected: step3. close success. + */ + CloseDb(); +} + +/** + * @tc.name: SchemaTest001 + * @tc.desc: Create table with Cloud cooperation mode and do sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, SchemaTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create table with Cloud cooperation mode + * @tc.expected: step1. return ok. + */ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, INTEGER_PRIMARY_KEY_TABLE_SQL_WRONG_SYNC_MODE), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName4, CLOUD_COOPERATION), DBStatus::OK); + /** + * @tc.steps:step1. do sync + * @tc.expected: step1. return ok. + */ + callSync({g_tableName4}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + CloseDb(); +} + +/** + * @tc.name: SchemaTest002 + * @tc.desc: Create table with DEVICE_COOPERATION mode and do sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, SchemaTest002, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create table with DEVICE_COOPERATION mode + * @tc.expected: step1. return ok. + */ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, INTEGER_PRIMARY_KEY_TABLE_SQL_WRONG_SYNC_MODE), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName4, DEVICE_COOPERATION), DBStatus::OK); + /** + * @tc.steps:step1. do sync + * @tc.expected: step1. return ok. + */ + callSync({g_tableName4}, SYNC_MODE_CLOUD_MERGE, DBStatus::NOT_SUPPORT); + CloseDb(); +} + } #endif // RELATIONAL_STORE diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp index 0f383bec..822ced03 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_save_cloud_data_test.cpp @@ -85,7 +85,7 @@ namespace { bool isIdPk = pkType == PrimaryKeyType::SINGLE_PRIMARY_KEY || pkType == PrimaryKeyType::COMPOSITE_PRIMARY_KEY; Field field1 = { "id", TYPE_INDEX, isIdPk, !isIdPk }; Field field2 = { "name", TYPE_INDEX, pkType == PrimaryKeyType::COMPOSITE_PRIMARY_KEY, true }; - Field field3 = { "age", TYPE_INDEX, pkType == PrimaryKeyType::COMPOSITE_PRIMARY_KEY, true }; + Field field3 = { "age", TYPE_INDEX, false, true }; Field field4 = { "sex", TYPE_INDEX, false, nullable }; Field field5 = { "image", TYPE_INDEX, false, true }; tableSchema = { g_tableName, { field1, field2, field3, field4, field5} }; @@ -110,7 +110,7 @@ namespace { sql = "create table " + tableName + "(id int, name TEXT, age REAL, sex INTEGER, image BLOB);"; } else { sql = "create table " + tableName + "(id int, name TEXT, age REAL, sex INTEGER, image BLOB," \ - " PRIMARY KEY(id, name, age))"; + " PRIMARY KEY(id, name))"; } EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); @@ -256,7 +256,6 @@ namespace { int64_t val = -1; // id is pk EXPECT_EQ(CloudStorageUtils::GetValueFromVBucket("id", dataInfoWithLog.primaryKeys, val), E_OK); - LOGD("ID = %d", val); } else if (pkType == PrimaryKeyType::COMPOSITE_PRIMARY_KEY) { EXPECT_TRUE(dataInfoWithLog.primaryKeys.find("id") != dataInfoWithLog.primaryKeys.end()); std::string name; @@ -898,4 +897,84 @@ namespace { EXPECT_EQ(count, 2); // 2 is result count EXPECT_EQ(sqlite3_close_v2(db), E_OK); } + + void DeleteWithPkTest(PrimaryKeyType pkType) + { + /** + * @tc.steps:step1. create db, create table. + * @tc.expected: step1. return ok. + */ + PrepareDataBase(g_tableName, pkType, false); + + /** + * @tc.steps:step2. call PutCloudSyncData + * @tc.expected: step2. return ok. + */ + std::shared_ptr storageProxy = GetStorageProxy(g_cloudStore); + ASSERT_NE(storageProxy, nullptr); + EXPECT_EQ(storageProxy->StartTransaction(TransactType::IMMEDIATE), E_OK); + + DownloadData downloadData; + VBucket vBucket; + vBucket["id"] = 1L; + if (pkType == PrimaryKeyType::COMPOSITE_PRIMARY_KEY) { + std::string name = "zhangsan1"; + vBucket["name"] = name; + } + + std::string gid = g_gid + "_not_exist"; // gid mismatch + vBucket[CloudDbConstant::GID_FIELD] = gid; + vBucket[CloudDbConstant::MODIFY_FIELD] = BASE_MODIFY_TIME; + downloadData.data.push_back(vBucket); + downloadData.opType = { OpType::DELETE }; + EXPECT_EQ(storageProxy->PutCloudSyncData(g_tableName, downloadData), E_OK); + EXPECT_EQ(storageProxy->Commit(), E_OK); + + /** + * @tc.steps:step3. verify data + * @tc.expected: step3. verify data ok. + */ + std::string sql; + if (pkType == PrimaryKeyType::SINGLE_PRIMARY_KEY) { + sql = "select count(1) from " + g_tableName + " where id = 1"; + } else { + sql = "select count(1) from " + g_tableName + " where id = 1 and name = 'zhangsan'"; + } + int count = 0; + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + int errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [&count] (sqlite3_stmt *stmt) { + EXPECT_EQ(sqlite3_column_int(stmt, 0), 0); + count++; + return OK; + }); + EXPECT_EQ(errCode, E_OK); + EXPECT_EQ(count, 1); + EXPECT_EQ(sqlite3_close_v2(db), E_OK); + } + + /** + * @tc.name: PutCloudSyncDataTest016 + * @tc.desc: Test delete data with pk in cloud data(normally there is no pk in cloud data when it is delete) + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, PutCloudSyncDataTest016, TestSize.Level1) + { + DeleteWithPkTest(PrimaryKeyType::SINGLE_PRIMARY_KEY); + } + + /** + * @tc.name: PutCloudSyncDataTest017 + * @tc.desc: Test delete data with pk in cloud data(normally there is no pk in cloud data when it is delete) + * primary key is COMPOSITE_PRIMARY_KEY + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ + HWTEST_F(DistributedDBCloudSaveCloudDataTest, PutCloudSyncDataTest017, TestSize.Level1) + { + DeleteWithPkTest(PrimaryKeyType::COMPOSITE_PRIMARY_KEY); + } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp index 88fa921f..025cc70c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp @@ -104,6 +104,52 @@ DataBaseSchema g_schema = { .nullable = true, } } + }, + { + .name = TABLE_NAME_3, + .fields = { + { + .colName = FIELD_NAME_1, + .type = TYPE_INDEX, + .primary = true, + .nullable = true, + }, + { + .colName = FIELD_NAME_2, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + }, + { + .colName = FIELD_NAME_3, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + } + } + }, + { + .name = TABLE_NAME_4, + .fields = { + { + .colName = FIELD_NAME_1, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + }, + { + .colName = FIELD_NAME_2, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + }, + { + .colName = FIELD_NAME_3, + .type = TYPE_INDEX, + .primary = false, + .nullable = true, + } + } } } }; @@ -191,6 +237,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest001, TestSize.Level0) table.AddField(field1); table.AddField(field2); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -215,6 +262,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest002, TestSize.Level0) table.AddField(field1); table.AddField(field2); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -244,6 +292,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest003, TestSize.Level0) table.AddField(field3); table.SetPrimaryKey(FIELD_NAME_1, 1); table.SetPrimaryKey(FIELD_NAME_3, 2); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -270,6 +319,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest004, TestSize.Level0) table.AddField(field2); table.AddField(field3); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -297,6 +347,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest005, TestSize.Level0) table.AddField(field2); table.AddField(field3); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -324,6 +375,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest006, TestSize.Level0) table.AddField(field2); table.AddField(field3); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -350,6 +402,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest007, TestSize.Level0) table.AddField(field2); table.AddField(field3); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -373,12 +426,14 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest008, TestSize.Level0) table.AddField(field1); table.AddField(field2); table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); TableInfo table2; table2.SetTableName(TABLE_NAME_1); table2.AddField(field1); table2.AddField(field2); table2.SetPrimaryKey(FIELD_NAME_1, 1); + table2.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); RelationalSchemaObject localSchema; localSchema.AddRelationalTable(table); @@ -413,4 +468,122 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest009, TestSize.Level0) EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_1, localSchema), -E_SCHEMA_MISMATCH); } +/** + * @tc.name: SchemaMgrTest010 + * @tc.desc: Test local schema with un-expected sync type + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest010, TestSize.Level0) +{ + FieldInfo field1 = SetField(FIELD_NAME_1, "int", true); + FieldInfo field2 = SetField(FIELD_NAME_2, "int", true); + FieldInfo field3 = SetField(FIELD_NAME_3, "int", true); + + TableInfo table; + table.SetTableName(TABLE_NAME_2); + table.AddField(field1); + table.AddField(field2); + table.AddField(field3); + table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::DEVICE_COOPERATION); + RelationalSchemaObject localSchema; + localSchema.AddRelationalTable(table); + + g_schemaMgr->SetCloudDbSchema(g_schema); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_2, localSchema), -E_NOT_SUPPORT); +} + +/** + * @tc.name: SchemaMgrTest011 + * @tc.desc: Test local schema with un-expected data type + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest011, TestSize.Level0) +{ + FieldInfo field1 = SetField(FIELD_NAME_1, "int", true); + FieldInfo field2 = SetField(FIELD_NAME_2, "text", true); + FieldInfo field3 = SetField(FIELD_NAME_3, "int", true); + + TableInfo table; + table.SetTableName(TABLE_NAME_2); + table.AddField(field1); + table.AddField(field2); + table.AddField(field3); + table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); + RelationalSchemaObject localSchema; + localSchema.AddRelationalTable(table); + + g_schemaMgr->SetCloudDbSchema(g_schema); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_2, localSchema), -E_SCHEMA_MISMATCH); +} + +/** + * @tc.name: SchemaMgrTest012 + * @tc.desc: table 3 contain primary asset field + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest012, TestSize.Level0) +{ + FieldInfo field1 = SetField(FIELD_NAME_1, "blob", true); + FieldInfo field2 = SetField(FIELD_NAME_2, "text", true); + FieldInfo field3 = SetField(FIELD_NAME_3, "int", true); + + TableInfo table; + table.SetTableName(TABLE_NAME_3); + table.AddField(field1); + table.AddField(field2); + table.AddField(field3); + table.SetPrimaryKey(FIELD_NAME_1, 1); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); + RelationalSchemaObject localSchema; + localSchema.AddRelationalTable(table); + + g_schemaMgr->SetCloudDbSchema(g_schema); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_3, localSchema), -E_SCHEMA_MISMATCH); +} + +/** + * @tc.name: SchemaMgrTest013 + * @tc.desc: table 4 do not contain primary assets field + * @tc.type: FUNC + * @tc.require: + * @tc.author: wanyi + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest013, TestSize.Level0) +{ + /** + * @tc.steps:step1. local schema's asset field is not primary + * @tc.expected: step1. return ok. + */ + FieldInfo field1 = SetField(FIELD_NAME_1, "blob", true); + FieldInfo field2 = SetField(FIELD_NAME_2, "text", true); + FieldInfo field3 = SetField(FIELD_NAME_3, "int", true); + + TableInfo table; + table.SetTableName(TABLE_NAME_4); + table.AddField(field1); + table.AddField(field2); + table.AddField(field3); + table.SetTableSyncType(TableSyncType::CLOUD_COOPERATION); + RelationalSchemaObject localSchema; + localSchema.AddRelationalTable(table); + + g_schemaMgr->SetCloudDbSchema(g_schema); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_4, localSchema), E_OK); + /** + * @tc.steps:step2. local schema's asset field is primary + * @tc.expected: step2. return E_SCHEMA_MISMATCH. + */ + table.SetPrimaryKey(FIELD_NAME_1, 1); + RelationalSchemaObject localSchemaWithAssetPrimary; + localSchemaWithAssetPrimary.AddRelationalTable(table); + EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_4, localSchemaWithAssetPrimary), -E_SCHEMA_MISMATCH); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_data_transformer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_data_transformer_test.cpp index b3c6b353..0648036f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_data_transformer_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_data_transformer_test.cpp @@ -204,7 +204,7 @@ HWTEST_F(DistributedDBDataTransformerTest, DataTransformerCheck001, TestSize.Lev EXPECT_EQ(DataTransformer::TransformTableData(originData, fieldInfoList, dataItemList), E_OK); OptTableDataWithLog targetData; - EXPECT_EQ(DataTransformer::TransformDataItem(dataItemList, fieldInfoList, fieldInfoList, targetData), E_OK); + EXPECT_EQ(DataTransformer::TransformDataItem(dataItemList, fieldInfoList, targetData), E_OK); EXPECT_TRUE(Equal(originData, targetData)); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp index b41bc2c5..c0ee9b2a 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp @@ -260,6 +260,23 @@ void fillCloudAssetTest(int64_t count, AssetStatus statusType, bool isFullReplac } } +void UpdateLocalAsset(const std::string &tableName, Asset &asset, int64_t rowid) +{ + sqlite3 *db = nullptr; + ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); + string sql = "UPDATE " + tableName + " SET assert = ? where rowid = '" + std::to_string(rowid) + "';"; + std::vector assetBlob; + int errCode; + RuntimeContext::GetInstance()->AssetToBlob(asset, assetBlob); + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); + if (SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false) == E_OK) { + EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + } + SQLiteUtils::ResetStatement(stmt, true, errCode); + sqlite3_close(db); +} + void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId, RelationalDBProperties &properties) { @@ -982,6 +999,40 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetCloudData005, TestS ASSERT_EQ(g_cloudStore->GetCloudDataNext(token, cloudSyncData), -E_INVALID_DB); } +/** + * @tc.name: GetCloudData006 + * @tc.desc: Test get cloud data which contains invalid status asset + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetCloudData006, TestSize.Level1) +{ + /** + * @tc.steps:step1. Init data and set asset status to invalid num + * @tc.expected: step1. return ok. + */ + CreateLogTable(); + int64_t insCount = 1024; + int64_t photoSize = 1024; + InitLogData(insCount, insCount, insCount, insCount); + CreateAndInitUserTable(2 * insCount, photoSize); // 2 is insert,update type data + Asset asset = g_localAsset; + asset.status = static_cast(AssetStatus::UPDATE) + 1; + UpdateLocalAsset(g_tableName, asset, 2L); // 2 is rowid + SetDbSchema(g_tableSchema); + + /** + * @tc.steps:step2. Get cloud data + * @tc.expected: step2. return -E_CLOUD_INVALID_ASSET. + */ + ContinueToken token = nullptr; + CloudSyncData cloudSyncData; + EXPECT_EQ(g_storageProxy->StartTransaction(TransactType::IMMEDIATE), E_OK); + ASSERT_EQ(g_storageProxy->GetCloudData(g_tableName, g_startTime, token, cloudSyncData), -E_CLOUD_INVALID_ASSET); + EXPECT_EQ(g_storageProxy->Rollback(), E_OK); +} + /** * @tc.name: GetInfoByPrimaryKeyOrGid001 * @tc.desc: Test the query of the GetInfoByPrimaryKeyOrGid interface to obtain assets. @@ -1191,5 +1242,114 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, FillCloudAsset004, Tes ASSERT_EQ(g_storageProxy->FillCloudGidAndAsset(OpType::INSERT, syncData), E_OK); EXPECT_EQ(g_storageProxy->Commit(), E_OK); } + +/* + * @tc.name: CalPrimaryKeyHash001 + * @tc.desc: Test CalcPrimaryKeyHash interface when primary key is string + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, CalPrimaryKeyHash001, TestSize.Level0) +{ + /** + * @tc.steps: step1. local insert one data, primary key is string + * @tc.expected: OK. + */ + std::string tableName = "user2"; + const std::string CREATE_LOCAL_TABLE_SQL = + "CREATE TABLE IF NOT EXISTS " + tableName + "(" \ + "name TEXT PRIMARY KEY, age INT);"; + sqlite3 *db = nullptr; + ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_LOCAL_TABLE_SQL), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DBStatus::OK); + std::string name = "Local0"; + std::map primaryKey = {{"name", name}}; + string sql = "INSERT OR REPLACE INTO user2(name, age) VALUES ('Local" + std::to_string(0) + "', '18');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); + std::vector result = RelationalStoreManager::CalcPrimaryKeyHash(primaryKey); + EXPECT_NE(result.size(), 0u); + std::string logTableName = RelationalStoreManager::GetDistributedLogTableName(tableName); + /** + * @tc.steps: step1. query timestamp use hashKey + * @tc.expected: OK. + */ + std::string querysql = "select timestamp/10000 from " + logTableName + " where hash_key=?"; + sqlite3_stmt *statement = nullptr; + int errCode = SQLiteUtils::GetStatement(db, querysql, statement); + EXPECT_EQ(errCode, E_OK); + errCode = SQLiteUtils::BindBlobToStatement(statement, 1, result); // 1 means hashkey index + if (errCode != E_OK) { + SQLiteUtils::ResetStatement(statement, true, errCode); + return; + } + errCode = SQLiteUtils::StepWithRetry(statement, false); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + Timestamp timestamp = static_cast(sqlite3_column_int64(statement, 0)); + LOGD("get timestamp = %" PRIu64, timestamp); + errCode = E_OK; + } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + errCode = -E_NOT_FOUND; + } + EXPECT_EQ(errCode, E_OK); + SQLiteUtils::ResetStatement(statement, true, errCode); + sqlite3_close(db); +} + +/* + * @tc.name: CalPrimaryKeyHash002 + * @tc.desc: Test CalcPrimaryKeyHash interface when primary key is int + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, CalPrimaryKeyHash002, TestSize.Level0) +{ + /** + * @tc.steps: step1. local insert one data, primary key is int + * @tc.expected: OK. + */ + std::string tableName = "user3"; + const std::string CREATE_LOCAL_TABLE_SQL = + "CREATE TABLE IF NOT EXISTS " + tableName + "(" \ + "id INT PRIMARY KEY, name TEXT);"; + sqlite3 *db = nullptr; + ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_LOCAL_TABLE_SQL), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DBStatus::OK); + int64_t id = 1; + std::map primaryKey = {{"id", id}}; + std::string sql = "INSERT OR REPLACE INTO " + tableName + " (id, name) VALUES ('" + '1' + "', 'Local" + + std::to_string(0) + "');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); + std::vector result = RelationalStoreManager::CalcPrimaryKeyHash(primaryKey); + EXPECT_NE(result.size(), 0u); + std::string logTableName = RelationalStoreManager::GetDistributedLogTableName(tableName); + /** + * @tc.steps: step1. query timestamp use hashKey + * @tc.expected: OK. + */ + std::string querysql = "select timestamp/10000 from " + logTableName + " where hash_key=?"; + sqlite3_stmt *statement = nullptr; + int errCode = SQLiteUtils::GetStatement(db, querysql, statement); + EXPECT_EQ(errCode, E_OK); + errCode = SQLiteUtils::BindBlobToStatement(statement, 1, result); // 1 means hashkey index + if (errCode != E_OK) { + SQLiteUtils::ResetStatement(statement, true, errCode); + return; + } + errCode = SQLiteUtils::StepWithRetry(statement, false); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + Timestamp timestamp = static_cast(sqlite3_column_int64(statement, 0)); + LOGD("get timestamp = %" PRIu64, timestamp); + errCode = E_OK; + } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + errCode = -E_NOT_FOUND; + } + EXPECT_EQ(errCode, E_OK); + SQLiteUtils::ResetStatement(statement, true, errCode); + sqlite3_close(db); +} } #endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp index 35fd9885..aba2381b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp @@ -1650,7 +1650,7 @@ HWTEST_F(DistributedDBRelationalGetDataTest, CloseStore001, TestSize.Level1) * @tc.steps: step2. release store. * @tc.expected: Succeed. */ - store->ReleaseDBConnection(connection); + store->ReleaseDBConnection(1, connection); // 1 is connection id RefObject::DecObjRef(store); store = nullptr; std::this_thread::sleep_for(std::chrono::seconds(1)); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_connection_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_connection_test.cpp index 500db15c..346a5e82 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_connection_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_connection_test.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include #include "distributeddb_data_generate_unit_test.h" @@ -442,4 +443,5 @@ HWTEST_F(DistributedDBStorageDataConnectionTest, ConnectionTest008, TestSize.Lev EXPECT_EQ(g_connection->Rekey(passwd), -E_BUSY); EXPECT_EQ(g_connection->Import(filePath, passwd), -E_BUSY); g_connection->UnRegisterObserver(handle); -} \ No newline at end of file +} +#endif // OMIT_MULTI_VER \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp index 79a29967..0b69464c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#ifndef OMIT_MULTI_VER #include #include "sqlite_import.h" @@ -453,7 +454,6 @@ HWTEST_F(DistributedDBStorageDataOperationTest, DeleteBatch001, TestSize.Level1) EXPECT_EQ(entriesRead.size(), 0UL); } -#ifndef OMIT_MULTI_VER static void CheckSplitData(const Value &oriValue, const uint32_t numBlock, std::map &valueDic, Value &savedValue) { @@ -689,7 +689,6 @@ HWTEST_F(DistributedDBStorageDataOperationTest, CutValueIntoBlock002, TestSize.L CheckRecoverData(savedValue, valueDic, value2); EXPECT_EQ(valueDic.size(), 0ul); } -#endif // OMIT_MULTI_VER /** * @tc.name: ShaAlgoEncryptTest001 @@ -971,4 +970,5 @@ HWTEST_F(DistributedDBStorageDataOperationTest, DeleteTableCallbackTest002, Test EXPECT_EQ(g_callbackTimes, 2); sqlite3_close_v2(db); db = nullptr; -} \ No newline at end of file +} +#endif // OMIT_MULTI_VER \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_store_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_store_test.cpp index 78db8eea..a172472e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_store_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_natural_store_test.cpp @@ -18,6 +18,7 @@ #include "db_constant.h" #include "db_common.h" #include "distributeddb_storage_single_ver_natural_store_testcase.h" +#include "mock_sqlite_single_ver_natural_store.h" using namespace testing::ext; using namespace DistributedDB; @@ -33,7 +34,6 @@ namespace { DistributedDB::SQLiteSingleVerNaturalStore *g_store = nullptr; DistributedDB::SQLiteSingleVerNaturalStoreConnection *g_connection = nullptr; -} class DistributedDBStorageSQLiteSingleVerNaturalStoreTest : public testing::Test { public: @@ -1112,4 +1112,39 @@ HWTEST_F(DistributedDBStorageSQLiteSingleVerNaturalStoreTest, ExportBusy001, Tes CipherPassword password; EXPECT_EQ(g_store->Export(g_testDir, password), -E_BUSY); g_store->ReEnableConnection(OperatePerm::NORMAL_WRITE); +} + +/** + * @tc.name: MigrationAndReleaseResourcesTest001 + * @tc.desc: concurrent test of Migration and ReleaseResources + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBStorageSQLiteSingleVerNaturalStoreTest, MigrationAndReleaseResourcesTest001, TestSize.Level1) +{ + KvDBProperties property; + property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir); + property.SetStringProp(KvDBProperties::STORE_ID, "TestGeneralNBMigration"); + property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, g_identifier); + property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE); + + int iterCount = 100; + for (int i = 0; i < iterCount; i++) { + DistributedDB::MockSqliteSingleVerNaturalStore *store = new(std::nothrow) MockSqliteSingleVerNaturalStore; + ASSERT_NE(store, nullptr); + + std::thread dataMigrationThread([&store]() { + store->CallAsyncDataMigration(); + }); + std::thread releaseThread([&store]() { + store->IncRefCount(); + store->CallReleaseResources(); + }); + + dataMigrationThread.join(); + releaseThread.join(); + store->DecObjRef(store); + } +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/mock_sqlite_single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/mock_sqlite_single_ver_natural_store.h new file mode 100644 index 00000000..24a74541 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/mock_sqlite_single_ver_natural_store.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_SQLITE_SINGLE_VER_NATURAL_STORE_H +#define MOCK_SQLITE_SINGLE_VER_NATURAL_STORE_H + +#include "sqlite_single_ver_natural_store.h" + +namespace DistributedDB { +class MockSqliteSingleVerNaturalStore : public SQLiteSingleVerNaturalStore { +public: + void CallAsyncDataMigration() const + { + SQLiteSingleVerNaturalStore::AsyncDataMigration(); + } + + void CallReleaseResources() + { + SQLiteSingleVerNaturalStore::ReleaseResources(); + } +}; +} +#endif // MOCK_SQLITE_SINGLE_VER_NATURAL_STORE_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h index 9175fdb4..02fad804 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h @@ -224,9 +224,9 @@ public: } std::map TestTagAssetsInSingleRecord( - VBucket &coveredData, VBucket &beCoveredData, bool WriteToCoveredData = false) + VBucket &coveredData, VBucket &beCoveredData, bool setNormalStatus = false) { - return TagAssetsInSingleRecord(coveredData, beCoveredData, WriteToCoveredData); + return TagAssetsInSingleRecord(coveredData, beCoveredData, setNormalStatus); } bool TestIsDataContainDuplicateAsset(std::vector &assetFields, VBucket &data) diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp index a07dfc00..3076c1b4 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp @@ -219,7 +219,6 @@ namespace { static bool IsAssetEq(Asset &target, Asset &expected) { if (target.name != expected.name || - target.flag != expected.flag || target.flag != expected.flag || target.status != expected.status) { return false; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp index 80458c5b..f254c1ba 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp @@ -531,6 +531,100 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest008, TestSize.Level0) EXPECT_EQ(proxy.Close(), E_OK); } +/** + * @tc.name: CloudDBProxyTest009 + * @tc.desc: Verify cloud db closed and current task exit . + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest009, TestSize.Level3) +{ + /** + * @tc.steps: step1. set cloud db to proxy and sleep 5s when download + * @tc.expected: step1. E_OK + */ + auto iCloud = std::make_shared(); + ASSERT_NE(iCloud, nullptr); + EXPECT_CALL(*iCloud, Commit).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, StartTransaction).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, Rollback).WillRepeatedly(testing::Return(E_OK)); + auto cloudSyncer = new(std::nothrow) VirtualCloudSyncer(StorageProxy::GetCloudDb(iCloud.get())); + ASSERT_NE(cloudSyncer, nullptr); + EXPECT_EQ(cloudSyncer->SetCloudDB(virtualCloudDb_), E_OK); + cloudSyncer->SetSyncAction(true, false); + cloudSyncer->SetDownloadFunc([]() { + std::this_thread::sleep_for(std::chrono::seconds(5)); // sleep 5s + return -E_CLOUD_ERROR; + }); + /** + * @tc.steps: step2. call sync and wait sync finish + * @tc.expected: step2. E_OK + */ + std::mutex processMutex; + bool finished = false; + std::condition_variable cv; + LOGI("[CloudDBProxyTest009] Call cloud sync"); + const auto callback = [&finished, &processMutex, &cv](const std::map &process) { + { + std::lock_guard autoLock(processMutex); + for (const auto &item: process) { + if (item.second.process == DistributedDB::FINISHED) { + finished = true; + EXPECT_EQ(item.second.errCode, DB_CLOSED); + } + } + } + cv.notify_all(); + }; + EXPECT_EQ(cloudSyncer->Sync({ "cloud" }, SyncMode::SYNC_MODE_CLOUD_MERGE, { TABLE_NAME }, callback, 0), E_OK); + std::this_thread::sleep_for(std::chrono::seconds(1)); + cloudSyncer->Close(); + { + LOGI("[CloudDBProxyTest009] begin to wait sync"); + std::unique_lock uniqueLock(processMutex); + cv.wait(uniqueLock, [&finished]() { + return finished; + }); + LOGI("[CloudDBProxyTest009] end to wait sync"); + } + RefObject::KillAndDecObjRef(cloudSyncer); +} + +/** + * @tc.name: CloudDBProxyTest010 + * @tc.desc: Verify cloud db lock with diff status. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest010, TestSize.Level0) +{ + /** + * @tc.steps: step1. set cloud db to proxy + * @tc.expected: step1. E_OK + */ + CloudDBProxy proxy; + EXPECT_EQ(proxy.SetCloudDB(virtualCloudDb_), E_OK); + /** + * @tc.steps: step2. proxy lock with diff status + */ + virtualCloudDb_->SetActionStatus(CLOUD_NETWORK_ERROR); + auto ret = proxy.Lock(); + EXPECT_EQ(ret.first, -E_CLOUD_NETWORK_ERROR); + EXPECT_EQ(TransferDBErrno(ret.first), CLOUD_NETWORK_ERROR); + + virtualCloudDb_->SetActionStatus(CLOUD_LOCK_ERROR); + ret = proxy.Lock(); + EXPECT_EQ(ret.first, -E_CLOUD_LOCK_ERROR); + EXPECT_EQ(TransferDBErrno(ret.first), CLOUD_LOCK_ERROR); + /** + * @tc.steps: step3. proxy close cloud db + * @tc.expected: step3. E_OK + */ + EXPECT_EQ(proxy.Close(), E_OK); +} + /** * @tc.name: CloudSyncQueue001 * @tc.desc: Verify sync task count decrease after sync finished. @@ -566,4 +660,39 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudSyncQueue001, TestSize.Level2) RuntimeContext::GetInstance()->StopTaskPool(); EXPECT_EQ(callCount, 1); } + +/** + * @tc.name: CloudSyncerTest001 + * @tc.desc: Verify syncer notify by queue schedule. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudSyncerTest001, TestSize.Level2) +{ + /** + * @tc.steps: step1. set cloud db to proxy + * @tc.expected: step1. E_OK + */ + auto iCloud = std::make_shared(); + EXPECT_CALL(*iCloud, StartTransaction).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, Commit).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, GetIdentify).WillRepeatedly(testing::Return("CloudSyncerTest001")); + auto cloudSyncer = new(std::nothrow) VirtualCloudSyncer(StorageProxy::GetCloudDb(iCloud.get())); + std::atomic callCount = 0; + cloudSyncer->SetCurrentTaskInfo([&callCount](const std::map &) { + callCount++; + int before = callCount; + LOGD("on callback %d", before); + std::this_thread::sleep_for(std::chrono::seconds(1)); + EXPECT_EQ(before, callCount); + }, 1u); + const int notifyCount = 2; + for (int i = 0; i < notifyCount; ++i) { + cloudSyncer->Notify(); + } + cloudSyncer->SetCurrentTaskInfo(nullptr, 0); // 0 is invalid task id + cloudSyncer->Close(); + RefObject::KillAndDecObjRef(cloudSyncer); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_strategy_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_strategy_test.cpp index 33328422..cda9f0a0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_strategy_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_strategy_test.cpp @@ -99,65 +99,66 @@ HWTEST_F(DistributedDBCloudStrategyTest, TagOpTyeTest001, TestSize.Level0) ASSERT_NE(strategy, nullptr); LogInfo localInfo; LogInfo cloudInfo; + std::set deletePrimaryKeySet; /** * @tc.steps: step2. local not exist cloud record * @tc.expected: step2. insert cloud record to local */ - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::INSERT); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::INSERT); /** * @tc.steps: step3. local record is newer and local not exist gid * @tc.expected: step3. only update gid */ localInfo.timestamp = 1u; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::ONLY_UPDATE_GID); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::ONLY_UPDATE_GID); /** * @tc.steps: step4. local record is newer and local exist gid * @tc.expected: step4. no need handle this record */ localInfo.cloudGid = "gid"; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); /** * @tc.steps: step5. cloud record is newer * @tc.expected: step5. update cloud record */ cloudInfo.timestamp = 2u; // mark 2 means cloud is new - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::UPDATE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::UPDATE); /** * @tc.steps: step6. cloud record is newer and it is delete * @tc.expected: step6. delete cloud record */ cloudInfo.flag = 0x01; // it means delete - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::DELETE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::DELETE); /** * @tc.steps: step7. cloud is new and local is delete * @tc.expected: step7 insert cloud record */ cloudInfo.flag = 0; // it means no delete localInfo.flag = 0x01; // it means delete - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::INSERT); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::INSERT); /** * @tc.steps: step8. cloud is new and local both delete * @tc.expected: step8 not handle cloud record */ cloudInfo.flag = 0x01; // it means delete - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::UPDATE_TIMESTAMP); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::UPDATE_TIMESTAMP); /** * @tc.steps: step9. cloud is delete and local not exist * @tc.expected: step9 not handle cloud record */ - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); /** * @tc.steps: step10. cloud is old and delete, local has gid * @tc.expected: step10 clear gid */ localInfo.timestamp = 3u; // mark 3 means local is new - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::CLEAR_GID); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::CLEAR_GID); /** * @tc.steps: step10. cloud is old and delete, local has not gid * @tc.expected: step10 not handle cloud record */ localInfo.cloudGid = ""; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); } /** @@ -176,38 +177,39 @@ HWTEST_F(DistributedDBCloudStrategyTest, TagOpTyeTest002, TestSize.Level0) ASSERT_NE(strategy, nullptr); LogInfo localInfo; LogInfo cloudInfo; + std::set deletePrimaryKeySet; /** * @tc.steps: step2. local not exist cloud record * @tc.expected: step2. not handle */ - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); /** * @tc.steps: step3. local has cloud record but don't have gid * @tc.expected: step3. only update gid */ - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::ONLY_UPDATE_GID); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::ONLY_UPDATE_GID); /** * @tc.steps: step4. local has cloud record and have gid * @tc.expected: step4. not handle */ localInfo.cloudGid = "gid"; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); localInfo.cloudGid = ""; /** * @tc.steps: step5. local has cloud record(without gid) but cloud flag is delete * @tc.expected: step5. ONLY UPDATE GID */ cloudInfo.flag = 0x01; // it means delete - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); /** * @tc.steps: step6. local has cloud record(with gid) but cloud flag is delete * @tc.expected: step6. CLEAR_GID */ localInfo.cloudGid = "gid"; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::CLEAR_GID); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::CLEAR_GID); } /** @@ -226,12 +228,14 @@ HWTEST_F(DistributedDBCloudStrategyTest, TagOpTyeTest003, TestSize.Level0) ASSERT_NE(strategy, nullptr); LogInfo localInfo; LogInfo cloudInfo; + std::set deletePrimaryKeySet; /** * @tc.steps: step2. local not exist cloud record(without gid) and its not deleted in cloud * @tc.expected: step2. insert */ - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::INSERT); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::INSERT); + deletePrimaryKeySet.clear(); /** * @tc.steps: step3. local not exist cloud record and it's deleted in cloud (without gid) @@ -239,31 +243,37 @@ HWTEST_F(DistributedDBCloudStrategyTest, TagOpTyeTest003, TestSize.Level0) */ localInfo.cloudGid = ""; cloudInfo.flag = 0x01; // it means delete - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::NOT_HANDLE); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::NOT_HANDLE); + deletePrimaryKeySet.clear(); /** * @tc.steps: step4. local not exist cloud record and it's deleted in cloud (with gid) * @tc.expected: step4. delete */ localInfo.cloudGid = "gid"; - EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo), OpType::DELETE); + EXPECT_EQ(strategy->TagSyncDataStatus(false, localInfo, cloudInfo, deletePrimaryKeySet), OpType::DELETE); + deletePrimaryKeySet.clear(); /** * @tc.steps: step5. local exist cloud record and its deleted in cloud * @tc.expected: step5. delete */ - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::DELETE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::DELETE); + deletePrimaryKeySet.clear(); localInfo.cloudGid = ""; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::DELETE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::DELETE); + deletePrimaryKeySet.clear(); /** * @tc.steps: step6. local exist cloud record and its not deleted in cloud(WITH OR WITHOUT gid) * @tc.expected: step6. UPDATE */ cloudInfo.flag = 0x00; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::UPDATE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::UPDATE); + deletePrimaryKeySet.clear(); localInfo.cloudGid = "gid"; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::UPDATE); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::UPDATE); + deletePrimaryKeySet.clear(); } /** * @tc.name: TagOpTyeTest004 @@ -281,14 +291,15 @@ HWTEST_F(DistributedDBCloudStrategyTest, TagOpTyeTest004, TestSize.Level0) ASSERT_NE(strategy, nullptr); LogInfo localInfo; LogInfo cloudInfo; + std::set deletePrimaryKeySet; cloudInfo.flag = 0x01; localInfo.flag = 0x01; localInfo.cloudGid = ""; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::UPDATE_TIMESTAMP); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::UPDATE_TIMESTAMP); cloudInfo.flag = 0x00; localInfo.flag = 0x01; - EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo), OpType::INSERT); + EXPECT_EQ(strategy->TagSyncDataStatus(true, localInfo, cloudInfo, deletePrimaryKeySet), OpType::INSERT); } } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp index f3ce7a7a..7af31ffc 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_progress_manager_test.cpp @@ -208,7 +208,8 @@ HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck003, TestSiz res = process.begin()->second; }, 5000); EXPECT_EQ(errCode, -E_INVALID_ARGS); - devices.emplace_back("0", DBConstant::MAX_DEV_LENGTH + 1); + std::string invalidDevice = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0'); + devices.emplace_back(invalidDevice); EXPECT_EQ(cloudSyncer5.Sync(devices, SYNC_MODE_CLOUD_MERGE, tables, nullptr, 5000), -E_INVALID_ARGS); // 5000 ms std::this_thread::sleep_for(std::chrono::seconds(1)); RuntimeContext::GetInstance()->StopTaskPool(); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp index dafc63b7..4b6cadc8 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp @@ -1105,199 +1105,4 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck018, TestSize.Level1 delete iCloud; idb = nullptr; } - -void MockMethod(const std::shared_ptr &idb, MockICloudSyncStorageInterface *iCloud) -{ - EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, BatchUpdate(_, _, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, BatchDelete(_, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END)); - EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { - count = 3000; // 3000 is upload count - return E_OK; - }); -} -/** - * @tc.name: UploadNotifyCheck001 - * @tc.desc: Test case about multiple tables in upload - * @tc.type: FUNC - * @tc.require: AR000HSNJO - * @tc.author: huangboxin - */ -HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadNotifyCheck001, TestSize.Level1) -{ - MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface(); - std::shared_ptr storageProxy = std::make_shared(iCloud); - TestCloudSyncer *cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy); - std::shared_ptr idb = std::make_shared(); - cloudSyncer->SetMockICloudDB(idb); - TaskId taskId = 17u; - cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); - std::string tableName2 = "TestTable2" + std::to_string(taskId); - std::vector tables = {cloudSyncer->GetCurrentContextTableName(), tableName2}; - SyncProcess res; - TableProcessInfo tbProcessInfo; - res.tableProcess[cloudSyncer->GetCurrentContextTableName()] = tbProcessInfo; - res.tableProcess[tableName2] = tbProcessInfo; - std::mutex mutex; - cloudSyncer->SetCurrentCloudTaskInfos(tables, [&res, &mutex]( - const std::map &process) { - std::lock_guard autoLock(mutex); - if (process.empty()) { - return; - } - res = process.begin()->second; - }); - CommonExpectCall(iCloud); - MockMethod(idb, iCloud); - CloudSyncData uploadData(cloudSyncer->GetCurrentContextTableName()); - cloudSyncer->initFullCloudSyncData(uploadData, 1000); // each size 1000 - CloudSyncData uploadData2(tableName2); - cloudSyncer->initFullCloudSyncData(uploadData2, 1000); // each size 1000 - - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData](const TableSchema &, const Timestamp &, - ContinueToken &, CloudSyncData &cloudDataResult) { - cloudDataResult = uploadData; - return E_OK;}) - .WillOnce([&uploadData2](const TableSchema &, const Timestamp &, - ContinueToken &, CloudSyncData &cloudDataResult) { - cloudDataResult = uploadData2; - return E_OK;}); - - EXPECT_EQ(cloudSyncer->CallDoSyncInner(cloudSyncer->GetCurrentCloudTaskInfos(), true), E_OK); - EXPECT_EQ(res.tableProcess[cloudSyncer->GetCurrentContextTableName()].process, PROCESSING); - cloudSyncer->CallNotify(); - RuntimeContext::GetInstance()->StopTaskPool(); - EXPECT_EQ(res.tableProcess[cloudSyncer->GetCurrentContextTableName()].process, FINISHED); - EXPECT_EQ(res.tableProcess[tableName2].process, FINISHED); - cloudSyncer->CallClose(); - RefObject::KillAndDecObjRef(cloudSyncer); - storageProxy.reset(); - delete iCloud; - idb = nullptr; -} - -/** - * @tc.name: UploadNotifyCheck002 - * @tc.desc: Test case about multiple tables in upload - * @tc.type: FUNC - * @tc.require: AR000HSNJO - * @tc.author: huangboxin - */ -HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadNotifyCheck002, TestSize.Level1) -{ - MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface(); - std::shared_ptr storageProxy = std::make_shared(iCloud); - TestCloudSyncer *cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy); - std::shared_ptr idb = std::make_shared(); - cloudSyncer->SetMockICloudDB(idb); - TaskId taskId = 17u; - cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); - std::string tableName2 = "TestTable2" + std::to_string(taskId); - std::vector tables = {cloudSyncer->GetCurrentContextTableName(), tableName2}; - SyncProcess res; - TableProcessInfo tbProcessInfo; - res.tableProcess[cloudSyncer->GetCurrentContextTableName()] = tbProcessInfo; - res.tableProcess[tableName2] = tbProcessInfo; - - std::mutex mutex; - cloudSyncer->SetCurrentCloudTaskInfos(tables, [&res, &mutex]( - const std::map &process) { - std::lock_guard autoLock(mutex); - if (process.empty()) { - return; - } - res = process.begin()->second; - }); - CommonExpectCall(iCloud); - // table A failed, table B will not be uploaded - EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillOnce(Return(OK)); - EXPECT_CALL(*idb, BatchUpdate(_, _, _)).WillOnce(Return(DB_ERROR)); - EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END)); - EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { - count = 3000; // total count is 3000 - return E_OK;}); - CloudSyncData uploadData(cloudSyncer->GetCurrentContextTableName()); - cloudSyncer->initFullCloudSyncData(uploadData, 1000); // each size 1000 - - EXPECT_CALL(*iCloud, GetCloudData(_, _, _, _)) - .WillOnce([&uploadData](const TableSchema &, const Timestamp &, - ContinueToken &, CloudSyncData &cloudDataResult) { - cloudDataResult = uploadData; - return E_OK;}); - - EXPECT_EQ(cloudSyncer->CallDoSyncInner(cloudSyncer->GetCurrentCloudTaskInfos(), true), -E_CLOUD_ERROR); - cloudSyncer->CallNotify(); - RuntimeContext::GetInstance()->StopTaskPool(); - EXPECT_EQ(res.tableProcess[cloudSyncer->GetCurrentContextTableName()].process, PROCESSING); - EXPECT_EQ(res.tableProcess[tableName2].process, PROCESSING); - cloudSyncer->CallClose(); - RefObject::KillAndDecObjRef(cloudSyncer); - storageProxy.reset(); - delete iCloud; - idb = nullptr; -} - -/** - * @tc.name: UploadNotifyCheck003 - * @tc.desc: Test case about multiple tables in upload - * @tc.type: FUNC - * @tc.require: AR000HSNJO - * @tc.author: huangboxin - */ -HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadNotifyCheck003, TestSize.Level1) -{ - MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface(); - std::shared_ptr storageProxy = std::make_shared(iCloud); - TestCloudSyncer *cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy); - std::shared_ptr idb = std::make_shared(); - cloudSyncer->SetMockICloudDB(idb); - TaskId taskId = 19u; - cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); - std::string tableName2 = "TestTable2" + std::to_string(taskId); - std::vector tables = { - cloudSyncer->GetCurrentContextTableName(), tableName2 - }; - SyncProcess res; - TableProcessInfo tbProcessInfo; - res.tableProcess[cloudSyncer->GetCurrentContextTableName()] = tbProcessInfo; - res.tableProcess[tableName2] = tbProcessInfo; - - std::mutex mutex; - cloudSyncer->SetCurrentCloudTaskInfos(tables, [&res, &mutex]( - const std::map &process) { - std::lock_guard autoLock(mutex); - if (process.empty()) { - return; - } - res = process.begin()->second; - }); - CommonExpectCall(iCloud); - EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, BatchUpdate(_, _, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, BatchDelete(_, _)).WillRepeatedly(Return(OK)); - EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END)); - EXPECT_CALL(*iCloud, FillCloudGid(_)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _)) - .WillRepeatedly([](const std::string &, const Timestamp &, const bool, int64_t & count) { - count = 0; - return E_OK; - }); - // test when count == 0 - EXPECT_EQ(cloudSyncer->CallDoSyncInner(cloudSyncer->GetCurrentCloudTaskInfos(), true), E_OK); - cloudSyncer->CallNotify(); - RuntimeContext::GetInstance()->StopTaskPool(); - EXPECT_EQ(res.tableProcess[cloudSyncer->GetCurrentContextTableName()].process, FINISHED); - EXPECT_EQ(res.tableProcess[tableName2].process, FINISHED); - cloudSyncer->CallClose(); - RefObject::KillAndDecObjRef(cloudSyncer); - storageProxy.reset(); - delete iCloud; - idb = nullptr; -} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h new file mode 100644 index 00000000..f694ef09 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_ASSET_LOADER_H +#define MOCK_ASSET_LOADER_H +#include +#include "iAssetLoader.h" + +namespace DistributedDB { +class MockAssetLoader : public IAssetLoader { +public: + MOCK_METHOD4(Download, DBStatus(const std::string &, const std::string &, const Type &, + std::map &)); + MOCK_METHOD1(RemoveLocalAssets, DBStatus(const std::vector &)); +}; +} +#endif // MOCK_ASSET_LOADER_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h index 2c182d39..6134e151 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h @@ -38,10 +38,11 @@ public: MOCK_METHOD4(GetInfoByPrimaryKeyOrGid, int(const std::string &, const VBucket &, DataInfoWithLog &, VBucket &)); MOCK_METHOD2(PutCloudSyncData, int(const std::string &, DownloadData &)); MOCK_METHOD3(TriggerObserverAction, void(const std::string &, ChangedData &&, bool)); - MOCK_METHOD3(CleanCloudData, int(ClearMode mode, const std::vector &tableNameList, - std::vector &assets)); + MOCK_METHOD4(CleanCloudData, int(ClearMode mode, const std::vector &tableNameList, + const RelationalSchemaObject &localSchema, std::vector &assets)); MOCK_METHOD3(FillCloudAssetForDownload, int(const std::string &, VBucket &, bool)); MOCK_METHOD2(FillCloudGidAndAsset, int(const OpType &, const CloudSyncData &)); + MOCK_CONST_METHOD0(GetIdentify, std::string()); }; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp index 119925b4..cd7ce427 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp @@ -19,6 +19,12 @@ namespace DistributedDB { DBStatus VirtualAssetLoader::Download(const std::string &tableName, const std::string &gid, const Type &prefix, std::map &assets) { + { + std::lock_guard autoLock(dataMutex_); + if (downloadStatus_ != OK) { + return downloadStatus_; + } + } LOGD("Download GID:%s", gid.c_str()); for (auto &item: assets) { for (auto &asset: item.second) { @@ -34,4 +40,10 @@ DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::vector &assets) return DBStatus::OK; } +void VirtualAssetLoader::SetDownloadStatus(DBStatus status) +{ + std::lock_guard autoLock(dataMutex_); + LOGD("[VirtualAssetLoader] set download status :%d", static_cast(status)); + downloadStatus_ = status; +} } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h index 7b8589d3..17203144 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h @@ -15,6 +15,7 @@ #ifndef VIRTUAL_ASSETLOADER_H #define VIRTUAL_ASSETLOADER_H +#include #include "iAssetLoader.h" namespace DistributedDB { @@ -27,6 +28,11 @@ public: std::map &assets) override; DBStatus RemoveLocalAssets(const std::vector &assets) override; + + void SetDownloadStatus(DBStatus status); +private: + std::mutex dataMutex_; + DBStatus downloadStatus_ = OK; }; } #endif // VIRTUAL_ASSETLOADER_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp index 5afb7d11..959e32c6 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.cpp @@ -17,12 +17,16 @@ #include #include "cloud_db_types.h" #include "db_constant.h" +#include "cloud_db_constant.h" #include "log_print.h" +#include "time_helper.h" + namespace DistributedDB { namespace { - const char *g_deleteField = "#_deleted"; - const char *g_gidField = "#_gid"; - const char *g_cursorField = "#_cursor"; + const char *g_deleteField = CloudDbConstant::DELETE_FIELD; + const char *g_gidField = CloudDbConstant::GID_FIELD; + const char *g_cursorField = CloudDbConstant::CURSOR_FIELD; + const char *g_modifiedField = CloudDbConstant::MODIFY_FIELD; } DBStatus VirtualCloudDb::BatchInsert(const std::string &tableName, std::vector &&record, @@ -57,6 +61,37 @@ DBStatus VirtualCloudDb::BatchInsert(const std::string &tableName, std::vector &&record, + std::vector &extend) +{ + if (cloudError_) { + return DB_ERROR; + } + if (blockTimeMs_ != 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(blockTimeMs_)); + } + if (record.size() != extend.size()) { + LOGE("[VirtualCloudDb] not equal records"); + return DB_ERROR; + } + std::lock_guard autoLock(cloudDataMutex_); + for (size_t i = 0; i < record.size(); ++i) { + if (extend[i].find(g_gidField) == extend[i].end()) { + extend[i][g_gidField] = std::to_string(currentGid_++); + } + extend[i][g_cursorField] = std::to_string(currentCursor_++); + extend[i][g_deleteField] = false; + CloudData cloudData = { + .record = std::move(record[i]), + .extend = extend[i] + }; + cloudData_[tableName].push_back(cloudData); + } + + LOGI("[VirtualCloudDb] BatchInsertWithGid records"); + return OK; +} + DBStatus VirtualCloudDb::BatchUpdate(const std::string &tableName, std::vector &&record, std::vector &extend) { @@ -105,6 +140,9 @@ DBStatus VirtualCloudDb::HeartBeat() std::pair VirtualCloudDb::Lock() { + if (actionStatus_ != OK) { + return { actionStatus_, DBConstant::MIN_TIMEOUT }; + } if (cloudError_) { return { DB_ERROR, DBConstant::MIN_TIMEOUT }; } @@ -135,6 +173,21 @@ DBStatus VirtualCloudDb::Close() return OK; } +DBStatus VirtualCloudDb::DeleteByGid(const std::string &tableName, VBucket &extend) +{ + for (auto &tableData : cloudData_[tableName]) { + if (std::get(tableData.extend[g_gidField]) == std::get(extend[g_gidField])) { + tableData.extend[g_modifiedField] = (int64_t)TimeHelper::GetSysCurrentTime() / + CloudDbConstant::TEN_THOUSAND; + tableData.extend[g_deleteField] = true; + LOGD("[VirtualCloudDb] DeleteByGid, gid %s", std::get(extend[g_gidField]).c_str()); + tableData.record.clear(); + break; + } + } + return OK; +} + DBStatus VirtualCloudDb::Query(const std::string &tableName, VBucket &extend, std::vector &data) { if (actionStatus_ != OK) { diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h index 4b7054c5..dc7a324f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_db.h @@ -27,6 +27,9 @@ public: DBStatus BatchInsert(const std::string &tableName, std::vector &&record, std::vector &extend) override; + DBStatus BatchInsertWithGid(const std::string &tableName, std::vector &&record, + std::vector &extend); + DBStatus BatchUpdate(const std::string &tableName, std::vector &&record, std::vector &extend) override; @@ -34,6 +37,8 @@ public: DBStatus Query(const std::string &tableName, VBucket &extend, std::vector &data) override; + DBStatus DeleteByGid(const std::string &tableName, VBucket &extend); + std::pair Lock() override; DBStatus UnLock() override; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp index 15afa3aa..576b044e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp @@ -74,4 +74,18 @@ size_t VirtualCloudSyncer::GetQueueCount() std::lock_guard autoLock(queueLock_); return taskQueue_.size(); } + +void VirtualCloudSyncer::SetCurrentTaskInfo(const SyncProcessCallback &callback, + CloudSyncer::TaskId taskId) +{ + { + std::lock_guard autoContextLock(contextLock_); + currentContext_.currentTaskId = taskId; + currentContext_.notifier = std::make_shared(this); + } + std::lock_guard autoLock(queueLock_); + CloudTaskInfo taskInfo; + taskInfo.callback = callback; + cloudTaskInfos_[taskId] = taskInfo; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h index ad35668a..66c10c26 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h @@ -33,6 +33,8 @@ public: void Notify(bool notifyIfError = false); size_t GetQueueCount(); + + void SetCurrentTaskInfo(const SyncProcessCallback &callback, CloudSyncer::TaskId taskId); private: std::function downloadFunc_; std::atomic doDownload_; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index c35cd16e..27cd9b0c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -371,6 +371,7 @@ void TimeSync001() for (int i = 0; i < loopCount; ++i) { MockTimeSync timeSync; EXPECT_EQ(timeSync.Initialize(communicator, metadata, storage, "DEVICES_A"), E_OK); + EXPECT_CALL(timeSync, SyncStart).WillRepeatedly(Return(E_OK)); timeSync.ModifyTimer(timeDriverMs); std::this_thread::sleep_for(std::chrono::milliseconds(timeDriverMs)); timeSync.Close(); @@ -1780,13 +1781,12 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncTaskContextCheck006, TestSize.Leve */ auto context = new (std::nothrow) SingleVerRelationalSyncTaskContext(); ASSERT_NE(context, nullptr); - VirtualCommunicator communicator("device", nullptr); + auto communicator = new (std::nothrow) VirtualCommunicator("device", nullptr); + ASSERT_NE(communicator, nullptr); VirtualSingleVerSyncDBInterface dbSyncInterface; - SingleVerSyncStateMachine stateMachine; std::shared_ptr metadata = std::make_shared(); ASSERT_EQ(metadata->Initialize(&dbSyncInterface), E_OK); - (void)stateMachine.Initialize(context, &dbSyncInterface, metadata, &communicator); - (void)context->Initialize("device", &dbSyncInterface, metadata, &communicator); + (void)context->Initialize("device", &dbSyncInterface, metadata, communicator); /** * @tc.steps: step2. add sync target into context */ @@ -1803,6 +1803,7 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncTaskContextCheck006, TestSize.Leve EXPECT_EQ(context->GetRetryTime(), 0); context->Clear(); RefObject::KillAndDecObjRef(context); + RefObject::KillAndDecObjRef(communicator); } #ifdef RUN_AS_ROOT /** @@ -2063,6 +2064,38 @@ HWTEST_F(DistributedDBMockSyncModuleTest, TimeSync001, TestSize.Level1) ASSERT_NO_FATAL_FAILURE(TimeSync001()); } +/** + * @tc.name: TimeSync002 + * @tc.desc: Test syncer call set sync retry before init. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, TimeSync002, TestSize.Level1) +{ + auto *storage = new(std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_NE(storage, nullptr); + auto *communicator = new(std::nothrow) MockCommunicator(); + ASSERT_NE(communicator, nullptr); + std::shared_ptr metadata = std::make_shared(); + + MockTimeSync timeSync; + EXPECT_CALL(timeSync, SyncStart).WillRepeatedly(Return(E_OK)); + EXPECT_EQ(timeSync.Initialize(communicator, metadata, storage, "DEVICES_A"), E_OK); + const int loopCount = 100; + const int timeDriverMs = 10; + for (int i = 0; i < loopCount; ++i) { + timeSync.ModifyTimer(timeDriverMs); + std::this_thread::sleep_for(std::chrono::milliseconds(timeDriverMs)); + timeSync.CallResetTimer(); + } + timeSync.Close(); + EXPECT_EQ(timeSync.CallIsClosed(), true); + metadata = nullptr; + delete storage; + RefObject::KillAndDecObjRef(communicator); +} + /** * @tc.name: SyncContextCheck001 * @tc.desc: Test context time out logic. @@ -2124,5 +2157,6 @@ HWTEST_F(DistributedDBMockSyncModuleTest, SyncTimerResetTest001, TestSize.Level1 EXPECT_EQ(stateMachine.CallStartWatchDog(), E_OK); EXPECT_EQ(stateMachine.CallPrepareNextSyncTask(), E_OK); + stateMachine.CallStopWatchDog(); } } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp index 2f000301..14fc7348 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp @@ -973,4 +973,39 @@ HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser013, TestSize.Level1) EXPECT_EQ(g_rdbDelegatePtr1->RemoveDeviceData("DEVICE"), OK); EXPECT_EQ(callCount, 0u); CloseStore(); +} + +/** + * @tc.name: multi user 014 + * @tc.desc: test remote query with multi user + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser014, TestSize.Level0) +{ + /** + * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active + */ + RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2); + /** + * @tc.steps: step2. openStore in dual tuple sync mode and call remote query + */ + OpenStore1(true); + PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1); + /** + * @tc.steps: step3. disable communicator and call remote query + * @tc.expected: step3. failed by communicator + */ + g_communicatorAggregator->DisableCommunicator(); + RemoteCondition condition; + condition.sql = "SELECT * FROM RdbMultiUser014"; + std::shared_ptr resultSet; + DBStatus status = g_rdbDelegatePtr1->RemoteQuery("DEVICE", condition, DBConstant::MAX_TIMEOUT, resultSet); + EXPECT_EQ(status, COMM_FAILURE); + EXPECT_EQ(resultSet, nullptr); + CloseStore(); + g_communicatorAggregator->EnableCommunicator(); + SyncActivationCheckCallbackV2 callbackV2 = nullptr; + RuntimeConfig::SetSyncActivationCheckCallback(callbackV2); } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index 96f00bbe..6298d9de 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -1193,7 +1193,6 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync001, TestSize.Leve */ Query query = Query::Select(g_tableName); EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK); - EXPECT_EQ(currentStatus, AutoLaunchStatus::WRITE_OPENED); /** * @tc.steps: step6. check sync data ensure sync successful */ @@ -1201,7 +1200,6 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, AutoLaunchSync001, TestSize.Leve OpenStore(); RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION); - EXPECT_EQ(currentStatus, AutoLaunchStatus::WRITE_CLOSED); } /** @@ -1758,7 +1756,7 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer005, TestSize.Level0) /* -* @tc.name: relation observer 001 +* @tc.name: relation observer 006 * @tc.desc: Test observer is destructed when sync finish * @tc.type: FUNC * @tc.require: @@ -1808,6 +1806,99 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer006, TestSize.Level3) RuntimeContext::GetInstance()->StopTaskPool(); } +/* +* @tc.name: relation observer 007 +* @tc.desc: Test open store observer will not overwrite autolaunch observer +* @tc.type: FUNC +* @tc.require: +* @tc.author: zhangshijie +*/ +HWTEST_F(DistributedDBRelationalVerP2PSyncTest, Observer007, TestSize.Level3) +{ + /** + * @tc.steps: step1. device A create table and device B insert data and device C don't insert data + * @tc.expected: step1. create and insert ok + */ + g_observer->ResetToZero(); + std::map dataMap; + PrepareVirtualEnvironment(dataMap, {g_deviceB, g_deviceC}); + + /** + * @tc.steps: step2. device A pull sync mode + * @tc.expected: step2. sync ok + */ + RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(observer, nullptr); + const AutoLaunchRequestCallback callback = [observer](const std::string &identifier, AutoLaunchParam ¶m) { + if (g_id != identifier) { + return false; + } + param.path = g_dbDir; + param.appId = APP_ID; + param.userId = USER_ID; + param.storeId = STORE_ID_1; + param.option.storeObserver = observer; +#ifndef OMIT_ENCRYPT + param.option.isEncryptedDb = true; + param.option.cipher = CipherType::DEFAULT; + param.option.passwd = g_correctPasswd; + param.option.iterateTimes = DEFAULT_ITER; +#endif + return true; + }; + + /** + * @tc.steps: step2. SetAutoLaunchRequestCallback + * @tc.expected: step2. success. + */ + g_mgr.SetAutoLaunchRequestCallback(callback); + + /** + * @tc.steps: step3. RunCommunicatorLackCallback + * @tc.expected: step3. success. + */ + LabelType labelType(g_id.begin(), g_id.end()); + g_communicatorAggregator->RunCommunicatorLackCallback(labelType); + + /** + * @tc.steps: step4. start sync + * @tc.expected: step4. success + */ + Query query = Query::Select(g_tableName); + g_rdbDelegatePtr->Sync({DEVICE_B}, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, false); + + /** + * @tc.steps: step5. open store with observer1 + * @tc.expected: step5. success. + */ + auto observer1 = new (std::nothrow) RelationalStoreObserverUnitTest(); + ASSERT_NE(observer1, nullptr); + RelationalStoreDelegate::Option option; + option.observer = observer1; +#ifndef OMIT_ENCRYPT + option.isEncryptedDb = true; + option.iterateTimes = DEFAULT_ITER; + option.passwd = g_isAfterRekey ? g_rekeyPasswd : g_correctPasswd; + option.cipher = CipherType::DEFAULT; +#endif + RelationalStoreDelegate *rdb1 = nullptr; + g_mgr.OpenStore(g_dbDir, STORE_ID_1, option, rdb1); + ASSERT_TRUE(rdb1 != nullptr); + + /** + * @tc.steps: step6. close store and delete observer1 + * @tc.expected: step6. success. + */ + ASSERT_EQ(g_mgr.CloseStore(rdb1), OK); + rdb1 = nullptr; + delete observer1; + observer1 = nullptr; + std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2 second to wait sync finish + std::this_thread::sleep_for(std::chrono::seconds(5)); // sleep 5 second to wait sync finish + RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_1, DBType::DB_RELATION); + RuntimeContext::GetInstance()->StopTaskPool(); +} + /** * @tc.name: remote query 001 @@ -2489,6 +2580,22 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, EncryptedAlgoUpgrade001, TestSiz CheckVirtualData(dataMap); } +/** + * @tc.name: QueryParamCheck001 + * @tc.desc: Test sync query param + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBRelationalVerP2PSyncTest, QueryParamCheck001, TestSize.Level0) +{ + std::map dataMap; + PrepareEnvironment(dataMap, {g_deviceB}); + Query query = Query::Select().FromTable({ g_tableName }); + EXPECT_EQ(g_rdbDelegatePtr->Sync({DEVICE_B}, DistributedDB::SYNC_MODE_PUSH_ONLY, query, nullptr, false), + NOT_SUPPORT); +} + #ifndef OMIT_ENCRYPT /** * @tc.name: AutoLaunchSyncAfterRekey_001 diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp index 8f121459..c8266fe7 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp @@ -1540,27 +1540,23 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, RebuildSync003, TestSize.Leve * @tc.steps: step4. device A rebuilt, device B push data to A and set clear remote data mark into context after 1s * * @tc.expected: step4. interface return ok */ - std::thread thread1([]() { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // wait 1s - g_deviceB->SetClearRemoteStaleData(true); - g_mgr.CloseKvStore(g_kvDelegatePtr); - g_kvDelegatePtr = nullptr; - ASSERT_TRUE(g_mgr.DeleteKvStore(STORE_ID) == OK); - KvStoreNbDelegate::Option option; - g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback); - ASSERT_TRUE(g_kvDelegateStatus == OK); - ASSERT_TRUE(g_kvDelegatePtr != nullptr); - std::map result; - std::vector devices = {g_deviceB->GetDeviceId()}; - g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, DATA_SYNC_MESSAGE); - ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result) == OK); - }); + g_deviceB->SetClearRemoteStaleData(true); + g_mgr.CloseKvStore(g_kvDelegatePtr); + g_kvDelegatePtr = nullptr; + ASSERT_TRUE(g_mgr.DeleteKvStore(STORE_ID) == OK); + KvStoreNbDelegate::Option option; + g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback); + ASSERT_TRUE(g_kvDelegateStatus == OK); + ASSERT_TRUE(g_kvDelegatePtr != nullptr); + std::map result; + std::vector devices = {g_deviceB->GetDeviceId()}; + g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, DATA_SYNC_MESSAGE); + ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result) == OK); /** * @tc.steps: step5. device B sync to A, make it clear history data and check data * * @tc.expected: step5. interface return ok */ EXPECT_EQ(g_deviceB->Sync(DistributedDB::SYNC_MODE_PUSH_ONLY, true), E_OK); - thread1.join(); EXPECT_EQ(g_deviceB->GetData(key3, item), -E_NOT_FOUND); EXPECT_EQ(g_kvDelegatePtr->Get(key1, actualValue), OK); EXPECT_EQ(actualValue, value); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp index c4593b97..eb4fc9eb 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp @@ -38,8 +38,9 @@ namespace { KvVirtualDevice *g_deviceB = nullptr; KvVirtualDevice *g_deviceC = nullptr; DeviceManager *g_deviceManager = nullptr; +#ifndef OMIT_MULTI_VER const int WAIT_TIME = 1000; -} +#endif class DistributedDBSyncerDeviceManagerTest : public testing::Test { public: @@ -208,6 +209,7 @@ HWTEST_F(DistributedDBSyncerDeviceManagerTest, GetDevices001, TestSize.Level0) EXPECT_TRUE(deviceList[0] == g_deviceB->GetDeviceId()); } +#ifndef OMIT_MULTI_VER /** * @tc.name: Send BroadCast 001 * @tc.desc: Test DeviceManager SendBroadCast function. @@ -239,4 +241,6 @@ HWTEST_F(DistributedDBSyncerDeviceManagerTest, SendBroadCast001, TestSize.Level1 ASSERT_TRUE(errCode == E_OK); EXPECT_TRUE(deviceBReviced); EXPECT_TRUE(deviceCReviced); +} +#endif // OMIT_MULTI_VER } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_single_ver_state_machine.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_single_ver_state_machine.h index 8598c3b5..1509eb63 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_single_ver_state_machine.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_single_ver_state_machine.h @@ -67,6 +67,11 @@ public: return SingleVerSyncStateMachine::StartWatchDog(); } + void CallStopWatchDog() + { + SingleVerSyncStateMachine::StopWatchDog(); + } + uint8_t GetCurrentState() { return currentState_; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_time_sync.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_time_sync.h index 09f2e7a7..dc5e8912 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_time_sync.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/mock_time_sync.h @@ -27,6 +27,18 @@ public: std::lock_guard lock(timeDriverLock_); RuntimeContext::GetInstance()->ModifyTimer(driverTimerId_, milliSeconds); } + + void CallResetTimer() + { + TimeSync::ResetTimer(); + } + + bool CallIsClosed() const + { + return TimeSync::IsClosed(); + } + + MOCK_METHOD2(SyncStart, int(const CommErrHandler &, uint32_t)); }; } #endif // MOCK_TIME_SYNC_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp index 5e2b6576..50b46eae 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp @@ -322,4 +322,20 @@ std::set VirtualCommunicatorAggregator::GetOnlineDevices() } return onlineDevices; } + +void VirtualCommunicatorAggregator::DisableCommunicator() +{ + std::lock_guard lock(communicatorsLock_); + for (const auto &communicator: communicators_) { + communicator.second->Disable(); + } +} + +void VirtualCommunicatorAggregator::EnableCommunicator() +{ + std::lock_guard lock(communicatorsLock_); + for (const auto &communicator: communicators_) { + communicator.second->Disable(); + } +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h index 1f77ed02..7cad9d98 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h @@ -83,6 +83,10 @@ public: std::set GetOnlineDevices(); + void DisableCommunicator(); + + void EnableCommunicator(); + ~VirtualCommunicatorAggregator() {}; VirtualCommunicatorAggregator() {}; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp index 3e5b5440..e8a4e265 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp @@ -90,8 +90,7 @@ int VirtualRelationalVerSyncDBInterface::PutSyncDataWithQuery(const QueryObject } OptTableDataWithLog optTableDataWithLog; optTableDataWithLog.tableName = query.GetTableName(); - int errCode = DataTransformer::TransformDataItem(dataItems, localFieldInfo_, - localFieldInfo_, optTableDataWithLog); + int errCode = DataTransformer::TransformDataItem(dataItems, localFieldInfo_, optTableDataWithLog); if (errCode != E_OK) { return errCode; } diff --git a/kv_store/test/unittest/distributedKVStore/config.json b/kv_store/test/unittest/distributedKVStore/config.json index c0c57b6b..b73d0310 100644 --- a/kv_store/test/unittest/distributedKVStore/config.json +++ b/kv_store/test/unittest/distributedKVStore/config.json @@ -18,7 +18,8 @@ "deviceType": [ "default", "tablet", - "phone" + "phone", + "2in1" ], "distro": { "deliveryWithInstall": true, diff --git a/kv_store/test/unittest/distributeddata/config.json b/kv_store/test/unittest/distributeddata/config.json index c0c57b6b..b73d0310 100644 --- a/kv_store/test/unittest/distributeddata/config.json +++ b/kv_store/test/unittest/distributeddata/config.json @@ -18,7 +18,8 @@ "deviceType": [ "default", "tablet", - "phone" + "phone", + "2in1" ], "distro": { "deliveryWithInstall": true, diff --git a/mock/include/CMakeLists.txt b/mock/include/CMakeLists.txt index e213231b..453e0bce 100644 --- a/mock/include/CMakeLists.txt +++ b/mock/include/CMakeLists.txt @@ -25,9 +25,12 @@ include_directories(${MOCK_DIR}/innerkits/config_policy/configpolicy_util/includ include_directories(${MOCK_DIR}/innerkits/faultloggerd/dfx_signalhandler/include) include_directories(${MOCK_DIR}/innerkits/faultloggerd/libfaultloggerd/include) include_directories(${MOCK_DIR}/innerkits/faultloggerd/lib_dfx_dump_catcher/include) -include_directories(${MOCK_DIR}/innerkits/netmanager_base/net_stats_manager_if/include) -include_directories(${MOCK_DIR}/innerkits/netmanager_base/net_conn_manager_if/include) -include_directories(${MOCK_DIR}/innerkits/netmanager_base/net_policy_manager_if/include) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/include) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/netconnclient/include) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/netconnclient/include/proxy) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/netmanagernative/include) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/netpolicyclient/include) +include_directories(${MOCK_DIR}/innerkits/netmanager_base/innerkits/netstatsclient/include) include_directories(${MOCK_DIR}/innerkits/accessibility/accessibilityconfig/include) include_directories(${MOCK_DIR}/innerkits/accessibility/accessibleability/include) include_directories(${MOCK_DIR}/innerkits/accessibility/accessibilityclient/include) @@ -117,6 +120,7 @@ include_directories(${MOCK_DIR}/innerkits/ability_runtime/ability_manager/includ include_directories(${MOCK_DIR}/innerkits/ability_runtime/abilitykit_native/include) include_directories(${MOCK_DIR}/innerkits/ability_runtime/app_manager/include/appmgr) include_directories(${MOCK_DIR}/innerkits/ability_runtime/dataobs_manager/include) +include_directories(${MOCK_DIR}/innerkits/ability_runtime/extension_manager/include) include_directories(${MOCK_DIR}/innerkits/ability_runtime/mock) include_directories(${MOCK_DIR}/innerkits/ability_runtime/napi_base_context/include) include_directories(${MOCK_DIR}/innerkits/ability_runtime/napi_common) @@ -214,4 +218,6 @@ include_directories(${MOCK_DIR}/kits/ability/native/continuation/remote_register include_directories(${MOCK_DIR}/kits/ability/native/distributed_ability_runtime) include_directories(${MOCK_DIR}/kits/ability/native/form_runtime) include_directories(${MOCK_DIR}/kits/ability/native) -include_directories(${MOCK_DIR}/sqlite/include) \ No newline at end of file +include_directories(${MOCK_DIR}/sqlite/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/file_api/interfaces/kits) +include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include) \ No newline at end of file diff --git a/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_interface.h b/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_interface.h index e6dc6679..6b10ed8a 100644 --- a/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_interface.h +++ b/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_interface.h @@ -43,9 +43,19 @@ public: * * @param changeInfo Indicates the info of the data to operate. */ - void OnChangeExt(const ChangeInfo &changeInfo){ + virtual void OnChangeExt(const ChangeInfo &changeInfo){ } + + /** + * @brief Called back to notify that the data being observed has changed. + * + * @param key Indicates the key that has changed. + */ + virtual void OnChangePreferences(const std::string &key) + { + return; + } }; } // namespace AAFwk } // namespace OHOS diff --git a/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_stub.h b/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_stub.h index e4bc346f..02f30f93 100644 --- a/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_stub.h +++ b/mock/innerkits/ability_runtime/dataobs_manager/include/data_ability_observer_stub.h @@ -46,6 +46,12 @@ private: */ int32_t OnChangeExtInner(MessageParcel &data, MessageParcel &reply); + /** + * @brief Called back to notify that the data being observed has changed. + * + */ + int32_t OnChangePreferencesInner(MessageParcel &data, MessageParcel &reply); + using RequestFuncType = int (DataAbilityObserverStub::*)(MessageParcel &data, MessageParcel &reply); static const RequestFuncType HANDLES[TRANS_BUTT]; diff --git a/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_client.h b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_client.h new file mode 100644 index 00000000..683fab25 --- /dev/null +++ b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_client.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_CLIENT_H +#define OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_CLIENT_H + +#include + +#include "extension_manager_interface.h" + +#include "iremote_object.h" + +namespace OHOS { +namespace AAFwk { +/** + * @class ExtensionManagerClient + * ExtensionManagerClient is used to access ability manager services. + */ +class ExtensionManagerClient { +public: + ExtensionManagerClient() = default; + virtual ~ExtensionManagerClient() = default; + static ExtensionManagerClient& GetInstance(); + + ErrCode ConnectServiceExtensionAbility(const Want &want, const sptr &connect, int32_t userId); + + ErrCode ConnectServiceExtensionAbility(const Want &want, const sptr &connect, + const sptr &callerToken, int32_t userId); + + /** + * Connect extension ability. + * + * @param want special want for the extension ability. + * @param connect callback used to notify caller the result of connecting. + * @param userId the extension runs in. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode ConnectExtensionAbility(const Want &want, const sptr &connect, + int32_t userId = DEFAULT_INVALID_USER_ID); + + /** + * Disconnect session with extension ability. + * + * @param connect Callback used to notify caller the result of disconnecting. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode DisconnectAbility(const sptr &connect); + +private: + class ExtensionMgrDeathRecipient : public IRemoteObject::DeathRecipient { + public: + ExtensionMgrDeathRecipient() = default; + ~ExtensionMgrDeathRecipient() = default; + void OnRemoteDied(const wptr& remote) override; + private: + DISALLOW_COPY_AND_MOVE(ExtensionMgrDeathRecipient); + }; + + sptr GetExtensionManager(); + void Connect(); + void ResetProxy(const wptr& remote); + + std::mutex mutex_; + sptr proxy_; + sptr deathRecipient_; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_CLIENT_H diff --git a/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_interface.h b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_interface.h new file mode 100644 index 00000000..faa02ae4 --- /dev/null +++ b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_interface.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_INTERFACE_H +#define OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_INTERFACE_H + +#include + +namespace OHOS { +namespace AppExecFwk { +enum class ExtensionAbilityType; +} +namespace AAFwk { +namespace { +constexpr int DEFAULT_INVALID_USER_ID = -1; +} +class Want; +/** + * @class IExtensionManager + * IExtensionManager interface is used to access ability manager services. + */ +class IExtensionManager : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.aafwk.ExtensionManager") + + /** + * Connect ability common method. + * + * @param want, special want for service type's ability. + * @param connect, callback used to notify caller the result of connecting or disconnecting. + * @param callerToken, caller ability token. + * @param extensionType, type of the extension. + * @param userId, the service user ID. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int ConnectAbilityCommon(const Want &want, const sptr &connect, + const sptr &callerToken, AppExecFwk::ExtensionAbilityType extensionType, + int32_t userId = DEFAULT_INVALID_USER_ID) + { + return 0; + } + + /** + * DisconnectAbility, disconnect session with service ability. + * + * @param connect, Callback used to notify caller the result of connecting or disconnecting. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int DisconnectAbility(const sptr &connect) = 0; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_INTERFACE_H diff --git a/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_proxy.h b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_proxy.h new file mode 100644 index 00000000..c5252717 --- /dev/null +++ b/mock/innerkits/ability_runtime/extension_manager/include/extension_manager_proxy.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_PROXY_H +#define OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_PROXY_H + +#include "extension_manager_interface.h" + +#include "iremote_proxy.h" + +namespace OHOS { +class MessageParcel; +namespace AAFwk { +enum class AbilityManagerInterfaceCode; +/** + * @class ExtensionManagerProxy + * ExtensionManagerProxy. + */ +class ExtensionManagerProxy : public IRemoteProxy { +public: + explicit ExtensionManagerProxy(const sptr &impl) : IRemoteProxy(impl) {} + virtual ~ExtensionManagerProxy() = default; + + /** + * ConnectAbility, connect session with service ability. + * + * @param want, Special want for service type's ability. + * @param connect, Callback used to notify caller the result of connecting or disconnecting. + * @param callerToken, caller ability token. + * @param userId, Designation User ID. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int ConnectAbilityCommon(const Want &want, const sptr &connect, + const sptr &callerToken, AppExecFwk::ExtensionAbilityType extensionType, + int32_t userId = DEFAULT_INVALID_USER_ID) override; + + /** + * DisconnectAbility, connect session with service ability. + * + * @param connect, Callback used to notify caller the result of connecting or disconnecting. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int DisconnectAbility(const sptr &connect) override; + +private: + bool WriteInterfaceToken(MessageParcel &data); + ErrCode SendRequest(AbilityManagerInterfaceCode code, MessageParcel &data, MessageParcel &reply, + MessageOption& option); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_EXTENSION_MANAGER_PROXY_H diff --git a/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_subscribe_info.h b/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_subscribe_info.h index f16d490c..e0b9f5ac 100644 --- a/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_subscribe_info.h +++ b/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_subscribe_info.h @@ -27,6 +27,7 @@ public: POST, // the event dispatch thread. ASYNC, // an asynchronous thread. BACKGROUND, // the background thread. + COMMON, // common listening thread of a process. }; /** diff --git a/mock/innerkits/dsoftbus/softbus_client/include/transport/session.h b/mock/innerkits/dsoftbus/softbus_client/include/transport/session.h index a2bcc355..f3e90aec 100644 --- a/mock/innerkits/dsoftbus/softbus_client/include/transport/session.h +++ b/mock/innerkits/dsoftbus/softbus_client/include/transport/session.h @@ -17,16 +17,15 @@ * @addtogroup SoftBus * @{ * -* @brief Provides high-speed, secure communication between devices. +* @brief Provides high-speed, secure communications between devices. * -* This module implements unified distributed communication capability management between +* This module implements unified distributed communication management of * nearby devices, and provides link-independent device discovery and transmission interfaces * to support service publishing and data transmission. * * @since 1.0 * @version 1.0 */ -/** @} */ /** * @file session.h @@ -35,8 +34,8 @@ * * This file provides data transmission capabilities, including creating and removing a session server, * opening and closing sessions, receiving data, and querying basic session information. \n -* After multiple nearby devices are discovered and networked, these interfaces can be used to -* transmit data across devices. \n +* You can use the interfaces to transmit data across the nearby devices that are discovered and networked. +* \n * * @since 1.0 * @version 1.0 @@ -49,166 +48,263 @@ #ifdef __cplusplus extern "C" { #endif + /** -* @brief business type of session +* @brief Enumerates the session types. * * @since 1.0 * @version 1.0 */ typedef enum { - TYPE_MESSAGE = 1, - TYPE_BYTES, - TYPE_FILE, - TYPE_STREAM, + TYPE_MESSAGE = 1, /**< Message */ + TYPE_BYTES, /**< Bytes */ + TYPE_FILE, /**< File */ + TYPE_STREAM, /**< Stream */ TYPE_BUTT, } SessionType; +/** +* @brief Enumerates the stream types. +* +* @since 1.0 +* @version 1.0 +*/ typedef enum { - INVALID = -1, - /* - * Send any segment of a frame each time. - */ - RAW_STREAM, - /* - * Send a whole video frame each time. - */ - COMMON_VIDEO_STREAM, - /* - * Send a whole audio frame each time. - */ - COMMON_AUDIO_STREAM, - /* - * Slice frame mode. - */ - VIDEO_SLICE_STREAM, + INVALID = -1, /**< Invalid stream type. */ + RAW_STREAM, /**< Send any segment of a frame each time. */ + COMMON_VIDEO_STREAM, /**< Send a whole video frame each time. */ + COMMON_AUDIO_STREAM, /**< Send a whole audio frame each time. */ + VIDEO_SLICE_STREAM, /**< Slice frame mode. */ } StreamType; +/** +* @brief Enumerates the link types. +* +* @since 1.0 +* @version 1.0 +*/ typedef enum { - LINK_TYPE_WIFI_WLAN_5G = 1, - LINK_TYPE_WIFI_WLAN_2G = 2, - LINK_TYPE_WIFI_P2P = 3, - LINK_TYPE_BR = 4, - LINK_TYPE_MAX = 4, + LINK_TYPE_WIFI_WLAN_5G = 1, /**< 5 GHz Wi-Fi link */ + LINK_TYPE_WIFI_WLAN_2G = 2, /**< 2.4 GHz Wi-Fi link */ + LINK_TYPE_WIFI_P2P = 3, /**< P2P link */ + LINK_TYPE_BR = 4, /**< BR link */ + LINK_TYPE_BLE = 5, + LINK_TYPE_WIFI_P2P_REUSE = 6, + LINK_TYPE_BLE_DIRECT = 7, + LINK_TYPE_COC = 8, + LINK_TYPE_COC_DIRECT = 9, + LINK_TYPE_MAX = 9, } LinkType; +#define MAX_MAC_LEN 18 + /** -* @brief session attribute. -* -* control the attribute of session. +* @brief Defines the session attributes. * * @since 1.0 * @version 1.0 */ typedef struct { - /** @brief dataType{@link SessionType} */ - int dataType; - int linkTypeNum; - LinkType linkType[LINK_TYPE_MAX]; + int dataType; /**< Session type {@link SessionType} */ + int linkTypeNum; /**< Number of link types */ + LinkType linkType[LINK_TYPE_MAX]; /**< Link type {@link LinkType} */ + /** + * @brief Defines the attributes. + * + * @since 1.0 + * @version 1.0 + */ union { + /** + * @brief Defines the stream attributes. + * + * @since 1.0 + * @version 1.0 + */ struct StreamAttr { - int streamType; + int streamType; /**< Stream type {@link StreamType} */ } streamAttr; } attr; + uint8_t *fastTransData; + uint16_t fastTransDataSize; } SessionAttribute; +/** +* @brief Defines the stream data. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - char *buf; - int bufLen; + char *buf; /**< Pointer to the buffer for storing the stream data */ + int bufLen; /**< Length of the buffer */ } StreamData; +/** +* @brief Defines the extended stream data. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - int type; - int64_t value; + int type; /**< Extended data type {@link TransEnumEventType} */ + int64_t value; /**< Value of the extended data */ } TV; +/** +* @brief Defines the frame information for stream transmission. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - int frameType; - int64_t timeStamp; - int seqNum; - int seqSubNum; - int level; - int bitMap; - int tvCount; - TV *tvList; + int frameType; /**< Frame type, which can be I-frame or P-frame. */ + int64_t timeStamp; /**< Timestamp. */ + int seqNum; /**< Sequence number. */ + int seqSubNum; /**< Sequence number of the slice. */ + int level; /**< Scalable video coding level. 0 stands for the base level, + 1 for level 1, and 2 for level 2. */ + int bitMap; /**< Bitmap, which indicates the start or end slice of a frame. */ + int tvCount; /**< Number of scalable tag-values (TVs). */ + TV *tvList; /**< Pointer to the TV list. */ } StreamFrameInfo; +/** +* @brief Enumerates the quality of service (QoS) types. +* +* @since 1.0 +* @version 1.0 +*/ typedef enum { - QOS_IMPROVE = 0, - QOS_RECOVER = 1 + QOS_IMPROVE = 0, /**< Improve QoS */ + QOS_RECOVER = 1, /**< Recover QoS */ } QosQuality; +/** +* @brief Enumerates the QoS feedback types. +* +* @since 1.0 +* @version 1.0 +*/ typedef enum { - TRANS_STREAM_QUALITY_EVENT = 1, - TRANS_CHANNEL_QUALITY_EVENT, - TRANS_CAN_DELAY_EVENT, - TRANS_CANT_DELAY_EVENT, - QOS_EVENT_MAX + TRANS_STREAM_QUALITY_EVENT = 1, /**< Feedback on stream transmission quality */ + TRANS_CHANNEL_QUALITY_EVENT, /**< Feedback on transmission channel quality */ + TRANS_CAN_DELAY_EVENT, /**< Feedback on deferrable transmission */ + TRANS_CANT_DELAY_EVENT, /**< Feedback on non-deferrable transmission */ + QOS_EVENT_MAX /**< Invalid feedback */ } QosEvent; +/** +* @brief Enumerates the stream transmission QoS event types. +* +* @since 1.0 +* @version 1.0 +*/ typedef enum { - WIFI_CHANNEL_QUALITY = 1, - FRAME_REALTIME_STATUS = 2, - BANDWIDTH_ESTIMATE_VALUE = 3, - JITTER_DETECTION_VALUE = 4, - STREAM_TRAFFIC_STASTICS = 5, + WIFI_CHANNEL_QUALITY = 1, /**< Wi-Fi channel quality */ + FRAME_REALTIME_STATUS = 2, /**< Real-time status of frame transmission */ + BANDWIDTH_ESTIMATE_VALUE = 3, /**< Bandwidth estimation */ + JITTER_DETECTION_VALUE = 4, /**< Jitter detection */ + STREAM_TRAFFIC_STASTICS = 5, /**< Stream traffic statistics */ } TransEnumEventType; +/** +* @brief Defines the Wi-Fi channel quality. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - int32_t channel; - int32_t score; + int32_t channel; /**< Wi-Fi channel */ + int32_t score; /**< Wi-Fi channel score */ } WifiChannelQuality; +/** +* @brief Defines the frame information. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - int32_t streamId; - int32_t seqNum; - int32_t level; - int32_t transStatus; - int32_t interval; + int32_t streamId; /**< Stream ID */ + int32_t seqNum; /**< Sequence number of the frame */ + int32_t level; /**< Frame layer number */ + int32_t transStatus; /**< Frame status */ + int32_t interval; /**< Duration that unsent frames in the queue are cached */ } FrameStatus; +/** +* @brief Defines the bandwidth detection information. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - uint32_t trend; - uint32_t rate; /* kbps */ + uint32_t trend; /**< Bandwidth change trend */ + uint32_t rate; /**< Bandwidth rate */ } BandwidthDetection; +/** +* @brief Defines the jitter estimation information. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - int32_t jitterLevel; - uint32_t bufferTime; /* ms */ + int32_t jitterLevel; /**< Estimated network status */ + uint32_t bufferTime; /**< Required buffer time */ } JitterEstimation; +/** +* @brief Defines the stream transmission statistics information. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - uint64_t statisticsGotTime; /* time point that stream traficc statistics are obtained (ms) */ - uint64_t periodRecvBits; - uint32_t pktNum; - uint32_t periodRecvPkts; - uint32_t periodRecvPktLoss; - uint32_t periodRecvRate; /* kbps */ - uint64_t periodRecvRateBps; /* bps */ - uint32_t periodRtt; /* ms */ - uint32_t periodRecvPktLossHighPrecision; /* for example when lost rate is 1.10%, then 110 will returned */ - uint32_t periodSendLostPkts; - uint32_t periodSendPkts; - uint32_t periodSendPktLossHighPrecision; /* for example when lost rate is 1.10%, then 110 will returned */ - uint64_t periodSendBits; - uint64_t periodSendRateBps; /* bps */ + uint64_t statisticsGotTime; /**< Time when the statistics information is obtained */ + uint64_t periodRecvBits; /**< Number of bits received in a transmission period */ + uint32_t pktNum; /**< Number of packets */ + uint32_t periodRecvPkts; /**< Number of packets received in a transmission period */ + uint32_t periodRecvPktLoss; /**< Number of RX packets lost in a transmission period */ + uint32_t periodRecvRate; /**< Receive rate in a transmission period, in kbit/s */ + uint64_t periodRecvRateBps; /**< RX rate in a transmission period, in bit/s */ + uint32_t periodRtt; /**< Round-trip time (RTT), in ms */ + + /**< RX packet loss rate displayed for high precision. + For example, if the packet loss rate is 1.10%, the value is 110. */ + uint32_t periodRecvPktLossHighPrecision; + uint32_t periodSendLostPkts; /**< Number of TX packets lost in a transmission period */ + uint32_t periodSendPkts; /**< Number of packets sent in a transmission period */ + + /**< TX packet loss rate displayed for high precision. + For example, if the packet loss rate is 1.10%, the value is 110. */ + uint32_t periodSendPktLossHighPrecision; + uint64_t periodSendBits; /**< Number of bits sent in a transmission period */ + uint64_t periodSendRateBps; /**< TX rate in a transmission period, in bps */ } StreamStatistics; +/** +* @brief Defines the video stream transmission QoS. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { - TransEnumEventType type; + TransEnumEventType type; /**< Stream transmission QoS event type {@link TransEnumEventType} */ union { - WifiChannelQuality wifiChannelInfo; - FrameStatus frameStatusInfo; - BandwidthDetection bandwidthInfo; - JitterEstimation jitterInfo; - StreamStatistics appStatistics; + WifiChannelQuality wifiChannelInfo; /**< Wi-Fi channel quality {@link WifiChannelQuality} */ + FrameStatus frameStatusInfo; /**< Frame information {@link FrameStatus} */ + BandwidthDetection bandwidthInfo; /**< Bandwidth detection {@link BandwidthDetection} */ + JitterEstimation jitterInfo; /**< Network jitter estimation {@link JitterEstimation} */ + StreamStatistics appStatistics; /**< Stream transmission statistics {@link StreamStatistics} */ } info; } QosTv; typedef enum { - /* Value type of this option is uint32_t, this option only can be get */ - SESSION_OPTION_MAX_SENDBYTES_SIZE = 0, - /* Value type of this option is uint32_t, this option only can be get */ - SESSION_OPTION_MAX_SENDMESSAGE_SIZE, + SESSION_OPTION_MAX_SENDBYTES_SIZE = 0, /**< Value type of this option is uint32_t, this option only can be get */ + SESSION_OPTION_MAX_SENDMESSAGE_SIZE, /**< Value type of this option is uint32_t, this option only can be get */ + SESSION_OPTION_LINK_TYPE, /**< Value type of this option is int32_t, this option only can be get */ SESSION_OPTION_BUTT, } SessionOption; @@ -225,12 +321,12 @@ typedef struct { /** * @brief Called when a session is opened. * - * This function can be used to verify the session or initialize resources related to the session. + * This callback is invoked to verify the session or initialize resources related to the session. * - * @param sessionId Indicates the session ID. - * @param result 0 if the session is opened successfully, returns an error code otherwise. - * @return Returns 0 if the session connection is accepted; returns a non-zero value - * otherwise (you do not need to call {@link CloseSession} to close the session). + * @param sessionId Indicates the unique session ID. + * @param result Indicates the result to return. + * @return Returns 0 if the session is set up; returns a non-zero value + * otherwise. You do not need to call {@link CloseSession} to close the session. * @since 1.0 * @version 1.0 */ @@ -239,10 +335,10 @@ typedef struct { /** * @brief Called when a session is closed. * - * This function can be used to release resources related to the session. + * This callback is invoked to release resources related to the session. * You do not need to call {@link CloseSession}. * - * @param sessionId Indicates the session ID. + * @param sessionId Indicates the unique session ID. * @since 1.0 * @version 1.0 */ @@ -251,9 +347,9 @@ typedef struct { /** * @brief Called when data is received. * - * This function is used to notify that data is received. + * This callback is invoked to notify that data is received. * - * @param sessionId Indicates the session ID. + * @param sessionId Indicates the unique session ID. * @param data Indicates the pointer to the data received. * @param dataLen Indicates the length of the data received. * @since 1.0 @@ -262,12 +358,12 @@ typedef struct { void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen); /** - * @brief Called when message is received. + * @brief Called when a message is received. * - * This function is used to notify that message is received. + * This callback is invoked to notify that a message is received. * - * @param sessionId Indicates the session ID. - * @param data Indicates the pointer to the message data received. + * @param sessionId Indicates the unique session ID. + * @param data Indicates the pointer to the message received. * @param dataLen Indicates the length of the message received. * @since 1.0 * @version 1.0 @@ -275,13 +371,14 @@ typedef struct { void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen); /** - * @brief Called when stream is received. + * @brief Called when stream data is received. * - * This function is used to notify that stream is received. + * This callback is invoked to notify that stream data is received. * - * @param sessionId Indicates the session ID. + * @param sessionId Indicates the unique session ID. * @param data Indicates the pointer to the stream data received. - * @param dataLen Indicates the length of the stream received. + * @param ext Indicates the pointer to the extended service data received. + * @param param Indicates the pointer to the stream data frame information. * @since 1.0 * @version 1.0 */ @@ -291,42 +388,140 @@ typedef struct { /** * @brief Called when QoS information is retrieved. * - * This function is used to notify that QoS information is retrieved. + * This callback is invoked to notify that QoS information is retrieved. * - * @param sessionId Indicates the session ID. - * @param eventId Indicates the type of QoS information, e.g., channel quality and stream quality - * @param tvCount Indicates the number of structure returned in the fourth parameters, i.e., tvList. - * @param tvList Indicates the detailed information of data transmission. + * @param sessionId Indicates the unique session ID. + * @param eventId Indicates the type of QoS information, such as the channel quality and stream quality. + * @param tvCount Indicates the number of TVs returned in the fourth parameter tvList. + * @param tvList Indicates the pointer to the TV list. * @since 1.0 * @version 1.0 */ void (*OnQosEvent)(int sessionId, int eventId, int tvCount, const QosTv *tvList); } ISessionListener; +/** +* @brief Defines the callbacks for file receiving. +* +* The callbacks are invoked to notify the file receiving status. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { + /** + * @brief Called when a file starts to be received. + * + * This callback is invoked to notify the start of file receiving. + * + * @param sessionId Indicates the unique session ID. + * @param files Indicates the pointer to the files to receive. + * @param fileCnt Indicates the number of files to receive. + * @return Returns 0 if the file receiving starts; returns a non-zero value otherwise. + * @since 1.0 + * @version 1.0 + */ int (*OnReceiveFileStarted)(int sessionId, const char *files, int fileCnt); + + /** + * @brief Called when a file is being received. + * + * This callback is invoked to notify that a file is being received. + * + * @param sessionId Indicates the unique session ID. + * @param files Indicates the pointer to the first file received. + * @param bytesUpload Indicates the size of the files received. + * @param bytesTotal Indicates the total size of the files to receive, in bytes. + * @return Returns 0 if a file is being received; returns a non-zero value otherwise. + * @since 1.0 + * @version 1.0 + */ int (*OnReceiveFileProcess)(int sessionId, const char *firstFile, uint64_t bytesUpload, uint64_t bytesTotal); + + /** + * @brief Called when the file receiving ends. + * + * This callback is invoked to notify the end of file receiving. + * + * @param sessionId Indicates the unique session ID. + * @param files Indicates the pointer to the files received. + * @param fileCnt Indicates the number of files received. + * @since 1.0 + * @version 1.0 + */ void (*OnReceiveFileFinished)(int sessionId, const char *files, int fileCnt); + + /** + * @brief Called when an error occurs during the file receiving process. + * + * This callback is invoked to notify a file receiving error. + * + * @param sessionId Indicates the unique session ID. + * @since 1.0 + * @version 1.0 + */ void (*OnFileTransError)(int sessionId); } IFileReceiveListener; +/** +* @brief Defines callbacks for file sending. +* +* The callbacks are invoked to notify the file sending status. +* +* @since 1.0 +* @version 1.0 +*/ typedef struct { + /** + * @brief Called when a file is being sent. + * + * This callback is invoked to notify that a file is being sent. + * + * @param sessionId Indicates the unique session ID. + * @param bytesUpload Indicates the size of the file sent, in bytes. + * @param bytesTotal Indicates the total size of the file to send, in bytes. + * @return Returns 0 if the file is being sent; returns a non-zero value otherwise. + * @since 1.0 + * @version 1.0 + */ int (*OnSendFileProcess)(int sessionId, uint64_t bytesUpload, uint64_t bytesTotal); + + /** + * @brief Called when the file sending ends. + * + * This callback is invoked to notify the end of file sending. + * + * @param sessionId Indicates the unique session ID. + * @param firstFile Indicates the pointer to the first file to send. + * @return Returns0 if the file sending is complete; returns a non-zero value otherwise. + * @since 1.0 + * @version 1.0 + */ int (*OnSendFileFinished)(int sessionId, const char *firstFile); + + /** + * @brief Called when an error occurs during the file sending process. + * + * This callback is invoked to notify a file sending error. + * + * @param sessionId Indicates the unique session ID. + * @since 1.0 + * @version 1.0 + */ void (*OnFileTransError)(int sessionId); } IFileSendListener; /** -* @brief Creates a session server based on a package name and session name. +* @brief Creates a session server. * * A maximum of 10 session servers can be created. * -* @param pkgName Indicates the pointer to the package name, which can be used to check whether the -* session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. +* @param pkgName Indicates the pointer to the service bundle name. +* It is the unique identifier of the upper-layer service. The value cannot be empty or exceed 64 characters. * @param sessionName Indicates the pointer to the session name, which is the unique ID of the session server. -* The value cannot be empty and can contain a maximum of 64 characters. -* @param listener Indicates the pointer to the session callback structure, which cannot be empty. -* The common error codes are as follows: +* The value cannot be empty or exceed 255 characters. +* @param listener Indicates the pointer to the session callback, which cannot be empty. +* * @return Returns 0 if the operation is successful; returns -1 otherwise. * @see RemoveSessionServer * @since 1.0 @@ -335,13 +530,12 @@ typedef struct { int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener); /** -* @brief Removes a session server based on a package name and session name. +* @brief Removes a session server. +* +* @param pkgName Indicates the pointer to the service bundle name. +* It is the unique identifier of the upper-layer service. The value cannot be empty or exceed 64 characters. +* @param sessionName Indicates the pointer to the session name. The value cannot be empty or exceed 255 characters. * -* @param pkgName Indicates the pointer to the name of the registered package, which can be used to check -* whether the session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. -* @param sessionName Indicates the pointer to the session name. The value cannot be empty and can contain -* a maximum of 64 characters. -* The common error codes are as follows: * @return Returns 0 if the operation is successful, returns -1 otherwise. * @see CreateSessionServer * @since 1.0 @@ -350,22 +544,23 @@ int CreateSessionServer(const char *pkgName, const char *sessionName, const ISes int RemoveSessionServer(const char *pkgName, const char *sessionName); /** -* @brief Initiate a session open request, which is an asynchronous process. +* @brief Opens a session, which is an asynchronous process. * -* The session connection is opened based on the service name to trigger the first packet interaction process. -* According to the {@link OnSessionOpened} Notify the user whether the session is successfully opened. +* The session is opened to trigger the first packet interaction process. +* {@link OnSessionOpened} is invoked to return whether the session is successfully opened. * Data can be transmitted only after the session is successfully opened. * -* @param mySessionName local session name. -* @param peerSessionName remote session name. -* @param peerNetworkId remote device id. -* @param groupId group id. -* @param attr session attribute {@link SessionAttribute}. -* The common error codes are as follows: -* @return SOFTBUS_TRANS_INVALID_PARAM invalid param. -* @return INVALID_SESSION_ID open session failed, and return invalid session id. -* @return return sessionId if the session is opened successfully, -* and the sessionId is greater than 0, returns other internal error codes otherwise. +* @param mySessionName Indicates the pointer to the local session name. +* @param peerSessionName Indicates the pointer to the remote session name. +* @param peerNetworkId Indicates the pointer to the remote device ID. +* @param Indicates the pointer to the group ID. This parameter can be left empty in automatic networking. +* In manual networking, you need to apply for a valid group ID from HiChain. +* @param attr Indicates the pointer to the session attributes {@link SessionAttribute}. +* +* @return Returns SOFTBUS_TRANS_INVALID_PARAM if invalid parameters are detected. +* @return Returns INVALID_SESSION_ID if the operation fails. +* @return Returns the session ID (an integer greater than 0) if the session is opened; +* returns an error code otherwise. * @since 1.0 * @version 1.0 */ @@ -373,132 +568,145 @@ int OpenSession(const char *mySessionName, const char *peerSessionName, const ch const char *groupId, const SessionAttribute* attr); /** -* @brief Closes a connected session based on a session ID. +* @brief Closes a session. * -* @param sessionId Indicates the session ID. -* @return no return value. +* @param sessionId Indicates the unique session ID. +* @return Returns no value. * @since 1.0 * @version 1.0 */ void CloseSession(int sessionId); /** -* @brief Sends data based on a session ID. +* @example sendbytes_message_demo.c +*/ + +/** +* @brief Sends data. * -* @param sessionId Indicates the session ID. +* @param sessionId Indicates the unique session ID. * @param data Indicates the pointer to the data to send, which cannot be NULL. -* @param len Indicates the length of the data to send. The maximum length cannot exceed 984 characters. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM param data or len of value is invalid. -* @return Returns SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT The data length exceeds the maximum limit. -* @return Returns SOFTBUS_TRANS_INVALID_SESSION_ID invalid session id. -* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE session is currently disable. -* @return Returns SOFTBUS_OK if the function is called successfully, return other internal errorcode otherwise. +* @param len Indicates the length of the data to send. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT if the data exceeds the maximum limit. +* @return Returns SOFTBUS_TRANS_INVALID_SESSION_ID if sessionId is invalid. +* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session is not open. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int SendBytes(int sessionId, const void *data, unsigned int len); /** -* @brief Sends message based on a session ID. +* @brief Sends a message. * -* @param sessionId Indicates the session ID. -* @param data Indicates the pointer to the message data to send, which cannot be NULL. +* @param sessionId Indicates the unique session ID. +* @param data Indicates the pointer to the message to send, which cannot be NULL. * @param len Indicates the length of the message to send. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM if the input data is NULL or len is Zero. -* @return Returns SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT The data length exceeds the maximum limit. -* @return Returns SOFTBUS_INVALID_SESSION_ID if the sessionId is invalid. -* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session current be enabled. -* @return Returns SOFTBUS_OK if the function is called successfully, return other internal errorcode otherwise. +* +* @return Returns SOFTBUS_INVALID_PARAM if data is NULL or len is zero. +* @return Returns SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT if the message length exceeds the limit. +* @return Returns SOFTBUS_INVALID_SESSION_ID if sessionId is invalid. +* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session is not open. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int SendMessage(int sessionId, const void *data, unsigned int len); /** -* @brief Sends stream based on a session ID. +* @example sendstream_demo.c +*/ + +/** +* @brief Sends stream data. * -* @param sessionId Indicates the session ID. +* @param sessionId Indicates the unique session ID. * @param data Indicates the pointer to the stream data to send, which cannot be NULL. -* @param ext Indicates the pointer to the ext stream data to send, which cannot be NULL. -* @param param Indicates the pointer to the stream data of param, which cannot be NULL. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM if the input param is NULL. -* @return Returns SOFTBUS_INVALID_SESSION_ID if the sessionId is invalid. -* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session current be enabled. -* @return Returns SOFTBUS_OK if the function is called successfully, return other internal errorcode otherwise. +* @param ext Indicates the pointer to the extended stream data to send, which cannot be NULL. +* @param param Indicates the pointer to the stream frame information, which cannot be NULL. +* +* @return Returns SOFTBUS_INVALID_PARAM if any of the input parameters is NULL. +* @return Returns SOFTBUS_INVALID_SESSION_ID if sessionId is invalid. +* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session is not open. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int SendStream(int sessionId, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param); /** -* @brief Obtains the session name registered by the local device based on the session ID. +* @example getsessioninfo_demo.c +*/ + +/** +* @brief Obtains the session name registered by the local device. * -* @param sessionId Indicates the session ID. +* @param sessionId Indicates the unique session ID. * @param sessionName Indicates the pointer to the buffer for storing the session name. * @param len Indicates the length of the buffer. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM Indicates invalid value for input param. -* @return Returns SOFTBUS_OK if the operation is successful, returns other internal error codes otherwise. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int GetMySessionName(int sessionId, char *sessionName, unsigned int len); /** -* @brief Obtains the session name registered by the peer device based on the session ID. +* @brief Obtains the session name registered by the peer device. * -* @param sessionId Indicates the session ID. +* @param sessionId Indicates the unique session ID. * @param sessionName Indicates the pointer to the buffer for storing the session name. * @param len Indicates the length of the buffer. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM Indicates invalid value for input param. -* @return Returns SOFTBUS_OK if the operation is successful, returns other internal error codes otherwise. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len); /** -* @brief Obtains the peer device ID based on a session ID. +* @brief Obtains the peer device ID. * -* @param sessionId Indicates the session ID. +* @param sessionId Indicates the unique session ID. * @param networkId Indicates the pointer to the buffer for storing the device ID. * @param len Indicates the length of the buffer. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM Indicates invalid value for input param. -* @return Returns SOFTBUS_OK if the operation is successful, returns other internal error codes otherwise. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int GetPeerDeviceId(int sessionId, char *networkId, unsigned int len); /** -* @brief Get session side based on a session ID. +* @brief Obtains the session role. * -* @param sessionId Indicates the session ID. -* @return Returns -1 Indicates get session side failed. -* @return Returns 0 Indicates the session is server side. -* @return Returns 1 Indicates the session is client side. +* @param sessionId Indicates the unique session ID. +* @return Returns -1 if the operation fails. +* @return Returns 0 if the session role is a server. +* @return Returns 1 if the session role is a client. * @since 1.0 * @version 1.0 */ int GetSessionSide(int sessionId); /** -* @brief Set file receive listener. +* @brief Sets a listener for file receiving. * -* @param pkgName Indicates the pointer to the name of the registered package, which can be used to check -* whether the session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. +* @param pkgName Indicates the pointer to the registered bundle name, which can be used to check +* whether the session server is in this package. The value cannot be empty or exceed 64 characters. * @param sessionName Indicates the pointer to the buffer for storing the session name. * @param recvListener Indicates the pointer to the file receive listener, which cannot be NULL. -* @param rootDir Indicates the length of the message to send. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM Indicates invalid value for input param. -* @return Returns SOFTBUS_TRANS_SESSION_ADDPKG_FAILED if add pkgName failed. -* @return Returns SOFTBUS_OKif the function is called successfully, return other internal errorcodes otherwise. +* @param rootDir Indicates the pointer to the root directory of the file. The length cannot exceed 255 bits. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_TRANS_SESSION_ADDPKG_FAILED if the bundle specified by pkgName +* fails to be added. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ @@ -506,33 +714,38 @@ int SetFileReceiveListener(const char *pkgName, const char *sessionName, const IFileReceiveListener *recvListener, const char *rootDir); /** -* @brief Set file sendListener based on pkgName and sessionName . +* @brief Sets a listener for file sending. * -* @param pkgName Indicates the pointer to the name of the registered package, which can be used to check -* whether the session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. +* @param pkgName Indicates the pointer to the service bundle name. +* It is the unique identifier of the upper-layer service. The value cannot be empty or exceed 64 characters. * @param sessionName Indicates the pointer to the buffer for storing the session name. * @param sendListener Indicates the pointer to the file send listener, which cannot be NULL. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM if the input param is invalid. -* @return Returns SOFTBUS_TRANS_SESSION_ADDPKG_FAILED if add pkgName failed. -* @return Returns SOFTBUS_OKif the function is called successfully, return other internal errorcodes otherwise. +* +* @return Returns SOFTBUS_INVALID_PARAM if invalid parameters are detected. +* @return Returns SOFTBUS_TRANS_SESSION_ADDPKG_FAILED if the bundle specified by pkgName +* fails to be added. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ int SetFileSendListener(const char *pkgName, const char *sessionName, const IFileSendListener *sendListener); /** -* @brief Sends file based on a session ID. +* @example sendfile_demo.c +*/ + +/** +* @brief Sends files. * -* @param sessionId Indicates the session ID. -* @param sFileList Indicates the pointer to the source file list to send, which cannot be NULL. -* @param dFileList Indicates the pointer to the destination file list to send, which cannot be NULL. -* @param fileCnt Indicates the number of files to send, whic cannot be 0. -* The common error codes are as follows: -* @return Returns SOFTBUS_INVALID_PARAM if the sFileList is NULL or fileCnt is Zero. -* @return Returns SOFTBUS_INVALID_SESSION_ID if the sessionId is invalid. -* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session current be enabled. -* @return Returns SOFTBUS_OKif the function is called successfully, return other internal errorcodes otherwise. +* @param sessionId Indicates the unique session ID. +* @param sFileList Indicates the pointer to the source files to send, which cannot be NULL. +* @param dFileList Indicates the pointer to the destination files, which cannot be NULL. +* @param fileCnt Indicates the number of files to send, which cannot be 0. +* +* @return Returns SOFTBUS_INVALID_PARAM if sFileList is NULL or fileCnt is 0. +* @return Returns SOFTBUS_INVALID_SESSION_ID if sessionId is invalid. +* @return Returns SOFTBUS_TRANS_SESSION_NO_ENABLE if the session is not open. +* @return Returns SOFTBUS_OK if the operation is successful; returns an error code otherwise. * @since 1.0 * @version 1.0 */ @@ -544,7 +757,7 @@ int SendFile(int sessionId, const char *sFileList[], const char *dFileList[], ui * @param sessionId Indicates the session ID. * @param option Indicates the session option type to get. * @param optionValue Indicates the session option value to get, which cannot be NULL. -* @param valueSize Indicates the size of data which optionValue point to, whic cannot be 0. +* @param valueSize Indicates the size of data which optionValue point to, which cannot be 0. * The common error codes are as follows: * @return Returns SOFTBUS_INVALID_PARAM if the option is invalid, optionValue is NULL or valueSize is Zero. * @return Returns SOFTBUS_INVALID_SESSION_ID if the sessionId is invalid. diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/BUILD.gn new file mode 100644 index 00000000..d9d3da33 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +es2abc_gen_abc("gen_backup_extension_ability_abc") { + src_js = rebase_path("backup_extension_ability.js") + dst_file = rebase_path(target_out_dir + "/backup_extension_ability.abc") + in_puts = [ "backup_extension_ability.js" ] + out_puts = [ target_out_dir + "/backup_extension_ability.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("backup_extension_ability_js") { + input = "backup_extension_ability.js" + output = target_out_dir + "/backup_extension_ability.o" +} + +gen_js_obj("backup_extension_ability_abc") { + input = get_label_info(":gen_backup_extension_ability_abc", + "target_out_dir") + "/backup_extension_ability.abc" + output = target_out_dir + "/backup_extension_ability_abc.o" + dep = ":gen_backup_extension_ability_abc" +} + +# 必须命名为backupextensionability或backupextensionability_napi +# 在将@ohos.application.BackupExtensionAblity翻译为库名时,只是将.作为目录分割符,然后将库名转换为小写后拼接.z.so或_napi.z.so后进行查找 +# 即,尝试加载/system/lib64/application/backupextensionability.z.so或/system//lib64/application/backupextensionability_napi.z.so +# 具体请参考//foundation/arkui/napi/module_manager/native_module_manager.cpp +ohos_shared_library("backupextensionability_napi") { + deps = [ + ":backup_extension_ability_abc", + ":backup_extension_ability_js", + "${path_backup}/frameworks/js/backup_ext:backupextensionability_napi_fwk", + ] + + relative_install_dir = "module/application" + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/backup_extension_ability.js b/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/backup_extension_ability.js new file mode 100644 index 00000000..1e21a35d --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/api/js/napi/backup_ext/backup_extension_ability.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class BackupExtensionAbility { + onBackup() { + console.log() + } + + onRestore(versionBackupedBundle) { + console.log(versionBackupedBundle) + } +} + +export default BackupExtensionAbility \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/file_share_sandbox.json b/mock/innerkits/filemanagement/app_file_service/interfaces/common/file_share_sandbox.json new file mode 100644 index 00000000..42914795 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/file_share_sandbox.json @@ -0,0 +1,52 @@ +{ + "mount-path-map" : [{ + "sandbox-path" : "/data/storage/el1/bundle", + "src-path" : "/data/app/el1/bundle/public/" + }, { + "sandbox-path" : "/data/storage/el2/base", + "src-path" : "/data/app/el2//base/" + }, { + "sandbox-path" : "/data/storage/el1/database", + "src-path" : "/data/app/el1//database/" + }, { + "sandbox-path" : "/data/storage/el2/database", + "src-path" : "/data/app/el2//database/" + }, { + "sandbox-path" : "/data/storage/el1/base", + "src-path" : "/data/app/el1//base/" + }, { + "sandbox-path" : "/data/storage/ark-cache", + "src-path" : "/data/local/ark-cache/" + }, { + "sandbox-path" : "/data/storage/ark-profile", + "src-path" : "/data/local/ark-profile//" + }, { + "sandbox-path" : "/data/storage/el2/distributedfiles", + "src-path" : "/mnt/hmdfs//account/merge_view/data/" + }, { + "sandbox-path" : "/mnt/data/fuse", + "src-path" : "/mnt/data//fuse" + }, { + "sandbox-path" : "/storage/local/Documents", + "src-path" : "/data/service/el2//hmdfs/account/files/Documents" + }, { + "sandbox-path" : "/storage/local/Download", + "src-path" : "/data/service/el2//hmdfs/account/files/Download" + }, { + "sandbox-path" : "/storage/local/Desktop", + "src-path" : "/data/service/el2//hmdfs/account/files/Desktop" + }, { + "sandbox-path" : "/storage/External", + "src-path" : "/mnt/data/External" + }, { + "sandbox-path" : "/storage/Share", + "src-path" : "/data/service/el1/public/storage_daemon/share/public" + }, { + "sandbox-path" : "/Documents", + "src-path" : "/data/service/el2//hmdfs/account/files/Documents" + }, { + "sandbox-path" : "/Download", + "src-path" : "/data/service/el2//hmdfs/account/files/Download" + } + ] +} \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/common_func.h b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/common_func.h new file mode 100644 index 00000000..d90a148f --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/common_func.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_COMMON_FUNC_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_COMMON_FUNC_H + +#include +#include + +namespace OHOS { +namespace AppFileService { +class CommonFunc { +public: + static std::string GetSelfBundleName(); + static std::string GetUriFromPath(const std::string &path); + static bool CheckPublicDirPath(const std::string &sandboxPath); +}; +} // namespace AppFileService +} // namespace OHOS + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_COMMON_FUNC_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/json_utils.h b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/json_utils.h new file mode 100644 index 00000000..eab45401 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/json_utils.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_COMMON_INCLUDE_JSON_UTILS_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_COMMON_INCLUDE_JSON_UTILS_H + +#include +#include +#include + +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace AppFileService { +class JsonUtils { +public: + static int32_t GetJsonObjFromPath(nlohmann::json& jsonObj, const std::string& jsonPath); + static int32_t GetKVFromJson(const nlohmann::json &json, const std::string &key, + std::string &value); +}; +} // AppFileService +} // OHOS +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_COMMON_INCLUDE_JSON_UTILS_H diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/log.h b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/log.h new file mode 100644 index 00000000..c941a611 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/log.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_LOG_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_LOG_H + +#include "hilog/log.h" + +namespace OHOS { +namespace AppFileService { +const unsigned int APP_LOG_DOMAIN = 0xD004313; +const char APP_LOG_TAG[] = "AppFileService"; +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, APP_LOG_DOMAIN, APP_LOG_TAG }; + +#define PRINT_LOG(Level, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Level(OHOS::AppFileService::LOG_LABEL, "[%{public}s:%{public}d] " fmt, \ + __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define LOGI(fmt, ...) PRINT_LOG(Info, fmt, ##__VA_ARGS__) +#define LOGW(fmt, ...) PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +#define LOGD(fmt, ...) PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +#define LOGE(fmt, ...) PRINT_LOG(Error, fmt, ##__VA_ARGS__) +#define LOGF(fmt, ...) PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +} // namespace AppFileService +} // namespace OHOS + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_LOG_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/sandbox_helper.h b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/sandbox_helper.h new file mode 100644 index 00000000..73745dc8 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/include/sandbox_helper.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_SANDBOX_HELPER_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_SANDBOX_HELPER_H + +#include +#include + +namespace OHOS { +namespace AppFileService { +class SandboxHelper { + static std::unordered_map sandboxPathMap_; +public: + static std::string Encode(const std::string &uri); + static std::string Decode(const std::string &uri); + static bool CheckValidPath(const std::string &filePath); + static int32_t GetPhysicalPath(const std::string &fileUri, const std::string &userId, + std::string &physicalPath); +}; +} // namespace AppFileService +} // namespace OHOS + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_INTERFACES_INNERKITS_NATIVE_COMMON_INCLUDE_SANDBOX_HELPER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/common_func.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/common_func.cpp new file mode 100644 index 00000000..875f0538 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/common_func.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common_func.h" + +#include + +#include "bundle_mgr_proxy.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +#include "log.h" +#include "sandbox_helper.h" + +using namespace std; + +namespace OHOS { +namespace AppFileService { +using namespace OHOS::AppExecFwk; +namespace { + const std::string FILE_SCHEME_PREFIX = "file://"; + const char BACKFLASH = '/'; + const std::vector PUBLIC_DIR_PATHS = { + "/Documents" + }; +} +static sptr GetBundleMgrProxy() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + LOGE("fail to get system ability mgr."); + return nullptr; + } + + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + LOGE("fail to get bundle manager proxy."); + return nullptr; + } + + return iface_cast(remoteObject); +} + +string CommonFunc::GetSelfBundleName() +{ + int uid = -1; + uid = IPCSkeleton::GetCallingUid(); + + sptr bundleMgrProxy = GetBundleMgrProxy(); + if (!bundleMgrProxy) { + LOGE("GetSelfBundleName: bundle mgr proxy is nullptr."); + return ""; + } + + BundleInfo bundleInfo; + auto ret = bundleMgrProxy->GetBundleInfoForSelf(uid, bundleInfo); + if (ret != ERR_OK) { + LOGE("GetSelfBundleName: bundleName get fail. uid is %{public}d", uid); + return ""; + } + + return bundleInfo.name; +} + +bool CommonFunc::CheckPublicDirPath(const std::string &sandboxPath) +{ + for (const std::string &path : PUBLIC_DIR_PATHS) { + if (sandboxPath.find(path) == 0) { + return true; + } + } + return false; +} + +static void NormalizePath(string &path) +{ + if (path.size() == 0) { + return; + } + + if (path[0] != BACKFLASH) { + path.insert(0, 1, BACKFLASH); + } +} + +string CommonFunc::GetUriFromPath(const string &path) +{ + string realPath = path; + NormalizePath(realPath); + + string packageName = GetSelfBundleName(); + realPath = FILE_SCHEME_PREFIX + packageName + realPath; + return SandboxHelper::Encode(realPath); +} +} // namespace AppFileService +} // namespace OHOS + diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/json_utils.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/json_utils.cpp new file mode 100644 index 00000000..2bc4eaff --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/json_utils.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "json_utils.h" + +#include +#include + +#include "log.h" + +namespace OHOS { +namespace AppFileService { + +int32_t JsonUtils::GetJsonObjFromPath(nlohmann::json& jsonObj, const std::string& jsonPath) +{ + std::ifstream jsonFileStream; + jsonFileStream.open(jsonPath.c_str(), std::ios::in); + if (!jsonFileStream.is_open()) { + LOGE("Open json file path %{public}s failed with error %{public}d", jsonPath.c_str(), errno); + return -errno; + } + + std::ostringstream buf; + char ch; + while (buf && jsonFileStream.get(ch)) { + buf.put(ch); + } + jsonFileStream.close(); + + jsonObj = nlohmann::json::parse(buf.str(), nullptr, false); + if (!jsonObj.is_structured()) { + LOGE("Parse json file path %{public}s failed", jsonPath.c_str()); + } + return 0; +} + +int32_t JsonUtils::GetKVFromJson(const nlohmann::json &json, const std::string &key, + std::string &value) +{ + if (!json.is_object()) { + LOGE("Invalid json object"); + return -EINVAL; + } + + bool ret = json.find(key) != json.end() && json.at(key).is_string(); + if (ret) { + value = json.at(key).get(); + return 0; + } else { + return -EINVAL; + } +} + +} // AppFileService +} // OHOS \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/sandbox_helper.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/sandbox_helper.cpp new file mode 100644 index 00000000..e30b78e7 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/common/src/sandbox_helper.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sandbox_helper.h" + +#include +#include +#include +#include + +#include "log.h" +#include "json_utils.h" +#include "uri.h" + +using namespace std; + +namespace OHOS { +namespace AppFileService { +namespace { + const string PACKAGE_NAME_FLAG = ""; + const string CURRENT_USER_ID_FLAG = ""; + const string PHYSICAL_PATH_KEY = "src-path"; + const string SANDBOX_PATH_KEY = "sandbox-path"; + const string MOUNT_PATH_MAP_KEY = "mount-path-map"; + const string SANDBOX_JSON_FILE_PATH = "/etc/app_file_service/file_share_sandbox.json"; +} +std::unordered_map SandboxHelper::sandboxPathMap_; + +string SandboxHelper::Encode(const string &uri) +{ + const unordered_set uriCompentsSet = { + ';', ',', '/', '?', ':', '@', '&', + '=', '+', '$', '-', '_', '.', '!', + '~', '*', '(', ')', '#', '\'' + }; + const int32_t encodeLen = 2; + ostringstream outPutStream; + outPutStream.fill('0'); + outPutStream << std::hex; + + for (unsigned char tmpChar : uri) { + if (std::isalnum(tmpChar) || uriCompentsSet.find(tmpChar) != uriCompentsSet.end()) { + outPutStream << tmpChar; + } else { + outPutStream << std::uppercase; + outPutStream << '%' << std::setw(encodeLen) << static_cast(tmpChar); + outPutStream << std::nouppercase; + } + } + + return outPutStream.str(); +} + +string SandboxHelper::Decode(const string &uri) +{ + std::ostringstream outPutStream; + const int32_t encodeLen = 2; + size_t index = 0; + while (index < uri.length()) { + if (uri[index] == '%') { + int hex = 0; + std::istringstream inputStream(uri.substr(index + 1, encodeLen)); + inputStream >> std::hex >> hex; + outPutStream << static_cast(hex); + index += encodeLen + 1; + } else { + outPutStream << uri[index]; + index++; + } + } + + return outPutStream.str(); +} + +static string GetLowerPath(string &lowerPathHead, const string &lowerPathTail, + const string &userId, const string &bundleName) +{ + if (lowerPathHead.find(CURRENT_USER_ID_FLAG) != string::npos) { + lowerPathHead = lowerPathHead.replace(lowerPathHead.find(CURRENT_USER_ID_FLAG), + CURRENT_USER_ID_FLAG.length(), userId); + } + + if (lowerPathHead.find(PACKAGE_NAME_FLAG) != string::npos) { + lowerPathHead = lowerPathHead.replace(lowerPathHead.find(PACKAGE_NAME_FLAG), + PACKAGE_NAME_FLAG.length(), bundleName); + } + + return lowerPathHead + lowerPathTail; +} + +static void GetSandboxPathMap(unordered_map &sandboxPathMap) +{ + nlohmann::json jsonObj; + int ret = JsonUtils::GetJsonObjFromPath(jsonObj, SANDBOX_JSON_FILE_PATH); + if (ret != 0) { + LOGE("Get json object failed from %{public}s with %{public}d", SANDBOX_JSON_FILE_PATH.c_str(), ret); + return; + } + + if (jsonObj.find(MOUNT_PATH_MAP_KEY) == jsonObj.end()) { + LOGE("Json object find mount path map failed"); + return; + } + + nlohmann::json mountPathMap = jsonObj[MOUNT_PATH_MAP_KEY]; + for (size_t i = 0; i < mountPathMap.size(); i++) { + string srcPath = mountPathMap[i][PHYSICAL_PATH_KEY]; + string sandboxPath = mountPathMap[i][SANDBOX_PATH_KEY]; + sandboxPathMap[sandboxPath] = srcPath; + } + return; +} + +int32_t SandboxHelper::GetPhysicalPath(const std::string &fileUri, const std::string &userId, + std::string &physicalPath) +{ + Uri uri(fileUri); + string bundleName = uri.GetAuthority(); + string sandboxPath = uri.GetPath(); + + string lowerPathTail = ""; + string lowerPathHead = ""; + + if (sandboxPathMap_.size() == 0) { + GetSandboxPathMap(sandboxPathMap_); + } + + for (auto it = sandboxPathMap_.begin(); it != sandboxPathMap_.end(); it++) { + string sandboxPathPrefix = it->first; + if (sandboxPath.length() >= sandboxPathPrefix.length()) { + string sandboxPathTemp = sandboxPath.substr(0, sandboxPathPrefix.length()); + if (sandboxPathTemp == sandboxPathPrefix) { + lowerPathHead = it->second; + lowerPathTail = sandboxPath.substr(sandboxPathPrefix.length()); + break; + } + } + } + + if (lowerPathHead == "") { + return -EINVAL; + } else { + physicalPath = GetLowerPath(lowerPathHead, lowerPathTail, userId, bundleName); + return 0; + } +} + +bool SandboxHelper::CheckValidPath(const std::string &filePath) +{ + if (filePath.empty() || filePath.size() >= PATH_MAX) { + return false; + } + + char realPath[PATH_MAX]{'\0'}; + if (realpath(filePath.c_str(), realPath) != nullptr && + strncmp(realPath, filePath.c_str(), filePath.size()) == 0) { + return true; + } else { + return false; + } +} +} // namespace AppFileService +} // namespace OHOS + diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/BUILD.gn new file mode 100644 index 00000000..2520bf7e --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +config("public_config") { + include_dirs = [ + ".", + "impl", + ] +} + +config("private_config") { + include_dirs = [ + "${path_backup}/frameworks/native/backup_kit_inner/include", + "${path_backup}/interfaces/inner_api/native/backup_kit_inner", + "${path_backup}/interfaces/inner_api/native/backup_kit_inner/impl", + ] +} + +ohos_shared_library("backup_kit_inner") { + sources = [ + "${path_backup}/frameworks/native/backup_kit_inner/src/b_file_info.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_backup.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_proxy.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp", + ] + + defines = [ + "LOG_DOMAIN=0xD004302", + "LOG_TAG=\"BackupAPI\"", + ] + + configs = [ ":private_config" ] + public_configs = [ ":public_config" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + deps = [ "${path_backup}/utils:backup_utils" ] + + use_exceptions = true + innerapi_tags = [ "platformsdk" ] + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h new file mode 100644 index 00000000..7277da99 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_BACKUP_KIT_INNER_H +#define OHOS_FILEMGMT_BACKUP_BACKUP_KIT_INNER_H + +#include "impl/b_session_backup.h" +#include "impl/b_session_restore.h" +#include "impl/b_session_restore_async.h" + +#endif // OHOS_FILEMGMT_BACKUP_BACKUP_KIT_INNER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_file_info.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_file_info.h new file mode 100644 index 00000000..356ad522 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_file_info.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_FILE_INFO_H +#define OHOS_FILEMGMT_BACKUP_B_FILE_INFO_H + +#include +#include + +#include "parcel.h" + +namespace OHOS::FileManagement::Backup { +using BundleName = std::string; +using TmpFileSN = uint32_t; + +struct BFileInfo : public Parcelable { + BundleName owner; + std::string fileName; + TmpFileSN sn; // 用于服务零拷贝接收文件场景 + + BFileInfo() = default; + BFileInfo(std::string bundleName, std::string strFileNanme, TmpFileSN id) + : owner(bundleName), fileName(strFileNanme), sn(id) {} + ~BFileInfo() override = default; + + bool ReadFromParcel(Parcel &parcel); + bool Marshalling(Parcel &parcel) const override; + static BFileInfo *Unmarshalling(Parcel &parcel); +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_FILE_INFO_H diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h new file mode 100644 index 00000000..059e3b79 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_SESSION_BACKUP_H +#define OHOS_FILEMGMT_BACKUP_B_SESSION_BACKUP_H + +#include +#include +#include + +#include "b_file_info.h" +#include "errors.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BSessionBackup { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的备份流程结束时执行的回调函数 + std::function onBundleFinished; // 当某个应用的备份流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个备份流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + +public: + /** + * @brief 获取一个用于控制备份流程的会话 + * + * @param callbacks 注册回调 + * @return std::unique_ptr 指向会话的智能指针。失败时为空指针 + */ + static std::unique_ptr Init(Callbacks callbacks); + + /** + * @brief 用于追加应用,现阶段仅支持在Start之前调用 + * + * @param bundlesToBackup 待备份的应用清单 + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(std::vector bundlesToBackup); + + /** + * @brief 用于结束追加应用,结束后不可在调用AppendBundles + * + * @return ErrCode 规范错误码 + */ + ErrCode Finish(); + + /** + * @brief 用于启动备份流程 + * + * @return ErrCode 规范错误码 + */ + ErrCode Start(); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +public: + ~BSessionBackup(); + +private: + sptr deathRecipient_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_SESSION_BACKUP_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h new file mode 100644 index 00000000..4654a7bc --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_H +#define OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_H + +#include +#include +#include + +#include "b_file_info.h" +#include "errors.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BSessionRestore { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的恢复流程结束时执行的回调函数 + std::function onBundleFinished; // 当某个应用的恢复流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个恢复流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + +public: + /** + * @brief 获取一个用于控制恢复流程的会话 + * + * @param callbacks 注册的回调函数 + * @return std::unique_ptr 指向BRestoreSession的智能指针。失败时为空指针 + */ + static std::unique_ptr Init(Callbacks callbacks); + + /** + * @brief 通知备份服务文件内容已就绪 + * + * @param fileInfo 文件描述信息 + * @return ErrCode 规范错误码 + * @see GetFileHandle + */ + ErrCode PublishFile(BFileInfo fileInfo); + + /** + * @brief 请求恢复流程所需的真实文件 + * + * @param bundleName 应用名称 + * @param fileName 文件名称 + */ + ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName); + + /** + * @brief 用于追加应用,现阶段仅支持在Start之前调用 + * + * @param remoteCap 已打开的保存远端设备能力的Json文件。可使用GetLocalCapabilities方法获取 + * @param bundlesToRestore 待恢复的应用清单 + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(UniqueFd remoteCap, std::vector bundlesToRestore); + + /** + * @brief 用于结束追加应用,结束后不可在调用AppendBundles + * + * @return ErrCode 规范错误码 + */ + ErrCode Finish(); + + /** + * @brief 用于启动恢复流程 + * + * @return ErrCode 规范错误码 + */ + ErrCode Start(); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +public: + ~BSessionRestore(); + +private: + sptr deathRecipient_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h new file mode 100644 index 00000000..0d547909 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_ASYNC_H +#define OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_ASYNC_H + +#include +#include +#include +#include +#include + +#include "b_file_info.h" +#include "errors.h" +#include "i_service.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BSessionRestoreAsync : public std::enable_shared_from_this { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的恢复流程结束时执行的回调函数 + std::function + onBundleFinished; // 当某个应用的恢复流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个恢复流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + + struct AppendBundleInfo { + UniqueFd remoteCap; // 已打开的保存远端设备能力的Json文件 + std::vector bundlesToRestore; // 需要恢复的应用名称列表 + RestoreTypeEnum restoreType; // 待恢复类型(例如升级服务数据迁移就绪无需进行数据传输) + int32_t userId; // 用户ID + }; + +public: + /** + * @brief 获取一个用于控制恢复流程的会话 + * + * @param callbacks 注册的回调函数 + * @return std::unique_ptr 指向BRestoreSession的智能指针。失败时为空指针 + */ + static std::shared_ptr Init(Callbacks callbacks); + + /** + * @brief 通知备份服务文件内容已就绪 + * + * @param fileInfo 文件描述信息 + * @return ErrCode 规范错误码 + * @see GetFileHandle + */ + ErrCode PublishFile(BFileInfo fileInfo); + + /** + * @brief 请求恢复流程所需的真实文件 + * + * @param bundleName 应用名称 + * @param fileName 文件名称 + */ + ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName); + + /** + * @brief 用于追加待恢复应用 + * + * @param remoteCap 已打开的保存远端设备能力的Json文件。可使用GetLocalCapabilities方法获取 + * @param bundlesToRestore 待恢复的应用清单 + * @param userId 用户ID + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(UniqueFd remoteCap, + std::vector bundlesToRestore, + RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND, + int32_t userId = DEFAULT_INVAL_VALUE); + +public: + explicit BSessionRestoreAsync(Callbacks callbacks) : callbacks_(callbacks) {}; + ~BSessionRestoreAsync(); + +private: + /** @brief 注册备份服务意外死亡时执行的回调函数 */ + void OnBackupServiceDied(); + + /** @brief 从暂存队列中取出一次待恢复应用请求 */ + void PopBundleInfo(); + + /** + * @brief 执行待恢复应用请求 + * + * @param info 待恢复应用请求信息 + */ + void AppendBundlesImpl(AppendBundleInfo info); + + /** + * @brief IPC请求异常时通知回调 + * + * @param errCode + * @param bundlesToRestore + */ + void OnBundleStarted(ErrCode errCode, const std::vector &bundlesToRestore); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +private: + sptr deathRecipient_; + Callbacks callbacks_; + std::atomic isAppend_ {false}; + std::mutex mutex_; + std::queue workList_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_ASYNC_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h new file mode 100644 index 00000000..ea565720 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_EXTENSION_H +#define OHOS_FILEMGMT_BACKUP_I_EXTENSION_H + +#include "errors.h" +#include "i_extension_ipc_interface_code.h" +#include "iremote_broker.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class IExtension : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileManagement.Backup.IExtension"); + +public: + virtual UniqueFd GetFileHandle(const std::string &fileName) = 0; + virtual ErrCode HandleClear() = 0; + virtual ErrCode HandleBackup() = 0; + virtual ErrCode PublishFile(const std::string &fileName) = 0; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_EXTENSION_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h new file mode 100644 index 00000000..4e76c4cc --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_EXTENSION_IPC_INTERFACE_CODE_H +#define OHOS_FILEMGMT_BACKUP_I_EXTENSION_IPC_INTERFACE_CODE_H + +/*SAID: 5203*/ +namespace OHOS::FileManagement::Backup { +enum class IExtensionInterfaceCode { + CMD_GET_FILE_HANDLE = 1, + CMD_HANDLE_CLAER, + CMD_PUBLISH_FILE, + CMD_HANDLE_BACKUP, +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_EXTENSION_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h new file mode 100644 index 00000000..e8bb2202 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_SERVICE_H +#define OHOS_FILEMGMT_BACKUP_I_SERVICE_H + +#include +#include + +#include + +#include "b_file_info.h" +#include "i_service_ipc_interface_code.h" +#include "i_service_reverse.h" +#include "iremote_broker.h" + +namespace OHOS::FileManagement::Backup { +const int DEFAULT_INVAL_VALUE = -1; + +typedef enum TypeRestoreTypeEnum { + RESTORE_DATA_WAIT_SEND = 0, + RESTORE_DATA_READDY = 1, +} RestoreTypeEnum; + +class IService : public IRemoteBroker { +public: + virtual ErrCode InitRestoreSession(sptr remote) = 0; + virtual ErrCode InitBackupSession(sptr remote) = 0; + virtual ErrCode Start() = 0; + virtual UniqueFd GetLocalCapabilities() = 0; + virtual ErrCode PublishFile(const BFileInfo &fileInfo) = 0; + virtual ErrCode AppFileReady(const std::string &fileName, UniqueFd fd) = 0; + virtual ErrCode AppDone(ErrCode errCode) = 0; + virtual ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName) = 0; + virtual ErrCode AppendBundlesRestoreSession(UniqueFd fd, + const std::vector &bundleNames, + RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND, + int32_t userId = DEFAULT_INVAL_VALUE) = 0; + virtual ErrCode AppendBundlesBackupSession(const std::vector &bundleNames) = 0; + virtual ErrCode Finish() = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Filemanagement.Backup.IService") +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_SERVICE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h new file mode 100644 index 00000000..79792104 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_SERVICE_IPC_INTERFACE_CODE_H +#define OHOS_FILEMGMT_BACKUP_I_SERVICE_IPC_INTERFACE_CODE_H + +/*SAID: 5203*/ +namespace OHOS::FileManagement::Backup { +enum class IServiceInterfaceCode { + SERVICE_CMD_INIT_RESTORE_SESSION, + SERVICE_CMD_INIT_BACKUP_SESSION, + SERVICE_CMD_GET_LOCAL_CAPABILITIES, + SERVICE_CMD_PUBLISH_FILE, + SERVICE_CMD_APP_FILE_READY, + SERVICE_CMD_APP_DONE, + SERVICE_CMD_START, + SERVICE_CMD_GET_FILE_NAME, + SERVICE_CMD_APPEND_BUNDLES_RESTORE_SESSION, + SERVICE_CMD_APPEND_BUNDLES_BACKUP_SESSION, + SERVICE_CMD_FINISH, +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_SERVICE_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h new file mode 100644 index 00000000..0d0f9a7f --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_H +#define OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_H + +#include + +#include "i_service_reverse_ipc_interface_code.h" +#include "iremote_broker.h" + +namespace OHOS::FileManagement::Backup { +class IServiceReverse : public IRemoteBroker { +public: + enum class Scenario { + UNDEFINED, + BACKUP, + RESTORE, + }; + +public: + virtual void BackupOnFileReady(std::string bundleName, std::string fileName, int fd) = 0; + virtual void BackupOnBundleStarted(int32_t errCode, std::string bundleName) = 0; + virtual void BackupOnBundleFinished(int32_t errCode, std::string bundleName) = 0; + virtual void BackupOnAllBundlesFinished(int32_t errCode) = 0; + + virtual void RestoreOnBundleStarted(int32_t errCode, std::string bundleName) = 0; + virtual void RestoreOnBundleFinished(int32_t errCode, std::string bundleName) = 0; + virtual void RestoreOnAllBundlesFinished(int32_t errCode) = 0; + virtual void RestoreOnFileReady(std::string bundleName, std::string fileName, int fd) = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileManagement.Backup.IServiceReverse") +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h new file mode 100644 index 00000000..5fc63b67 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_IPC_INTERFACE_CODE_H +#define OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_IPC_INTERFACE_CODE_H + +/*SAID: 5203*/ +namespace OHOS::FileManagement::Backup { +enum class IServiceReverseInterfaceCode { + SERVICER_BACKUP_ON_FILE_READY, + SERVICER_BACKUP_ON_SUB_TASK_STARTED, + SERVICER_BACKUP_ON_SUB_TASK_FINISHED, + SERVICER_BACKUP_ON_TASK_FINISHED, + SERVICER_RESTORE_ON_SUB_TASK_STARTED, + SERVICER_RESTORE_ON_SUB_TASK_FINISHED, + SERVICER_RESTORE_ON_TASK_FINISHED, + SERVICER_RESTORE_ON_FILE_READY, +}; + +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_SERVICE_REVERSE_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h new file mode 100644 index 00000000..5273921a --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_SERVICE_PROXY_H +#define OHOS_FILEMGMT_BACKUP_SERVICE_PROXY_H + +#include +#include +#include +#include + +#include "i_service.h" +#include "iremote_proxy.h" +#include "system_ability_load_callback_stub.h" + +namespace OHOS::FileManagement::Backup { +class ServiceProxy : public IRemoteProxy { +public: + ErrCode InitRestoreSession(sptr remote) override; + ErrCode InitBackupSession(sptr remote) override; + ErrCode Start() override; + UniqueFd GetLocalCapabilities() override; + ErrCode PublishFile(const BFileInfo &fileInfo) override; + ErrCode AppFileReady(const std::string &fileName, UniqueFd fd) override; + ErrCode AppDone(ErrCode errCode) override; + ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName) override; + ErrCode AppendBundlesRestoreSession(UniqueFd fd, + const std::vector &bundleNames, + RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND, + int32_t userId = DEFAULT_INVAL_VALUE) override; + ErrCode AppendBundlesBackupSession(const std::vector &bundleNames) override; + ErrCode Finish() override; + +public: + explicit ServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} + ~ServiceProxy() override {} + +public: + static sptr GetInstance(); + static void InvaildInstance(); + +public: + class ServiceProxyLoadCallback : public SystemAbilityLoadCallbackStub { + public: + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; + + public: + std::condition_variable proxyConVar_; + std::atomic isLoadSuccess_ = {false}; + }; + +private: + static inline std::mutex proxyMutex_; + static inline sptr serviceProxy_ = nullptr; + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_SERVICE_PROXY_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/svc_death_recipient.h b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/svc_death_recipient.h new file mode 100644 index 00000000..d7d9d294 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner/impl/svc_death_recipient.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_SVC_DEATH_RECIPIENT_H +#define OHOS_FILEMGMT_BACKUP_SVC_DEATH_RECIPIENT_H + +#include + +#include "iremote_object.h" + +namespace OHOS::FileManagement::Backup { +class SvcDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr &object) override + { + object->RemoveDeathRecipient(this); + functor_(object); + }; + +public: + explicit SvcDeathRecipient(std::function &)> functor) : functor_(functor) {}; + +private: + std::function &)> functor_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_SVC_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/BUILD.gn new file mode 100644 index 00000000..25f54d03 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/BUILD.gn @@ -0,0 +1,131 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/app_file_service.gni") + +config("file_share_config") { + visibility = [ ":*" ] + include_dirs = [ + "file_share/include", + "//third_party/json/include", + "../../common/include", + ] +} + +config("file_uri_config") { + visibility = [ ":*" ] + include_dirs = [ + "file_uri/include", + "//third_party/json/include", + "../../common/include", + ] +} + +ohos_shared_library("fileshare_native") { + sources = [ + "../../common/src/json_utils.cpp", + "../../common/src/sandbox_helper.cpp", + "file_share/src/file_share.cpp", + ] + + public_configs = [ ":file_share_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "ability_base:zuri", + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hilog:libhilog", + ] + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_shared_library("fileuri_native") { + sources = [ + "../../common/src/common_func.cpp", + "../../common/src/json_utils.cpp", + "../../common/src/sandbox_helper.cpp", + "file_uri/src/file_uri.cpp", + ] + + public_configs = [ ":file_uri_config" ] + + external_deps = [ + "ability_base:zuri", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_prebuilt_etc("file_share_sandbox.json") { + source = "../../common/file_share_sandbox.json" + part_name = "app_file_service" + subsystem_name = "filemanagement" + module_install_dir = "etc/app_file_service" +} + +config("remote_file_share_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "${utils_system_safwk_path}/native/include", + "remote_file_share/include", + "//third_party/json/include", + "${path_base}/include", + "../../common/include", + ".", + ] +} + +ohos_shared_library("remote_file_share_native") { + sources = [ + "../../common/src/json_utils.cpp", + "../../common/src/sandbox_helper.cpp", + "remote_file_share/src/remote_file_share.cpp", + ] + + public_configs = [ ":remote_file_share_config" ] + + external_deps = [ + "ability_base:zuri", + "c_utils:utils", + "hilog:libhilog", + ] + + innerapi_tags = [ "platformsdk_indirect" ] + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +group("app_file_service_native") { + deps = [ + ":fileshare_native", + ":fileuri_native", + ":remote_file_share_native", + ] +} + +group("etc_files") { + deps = [ ":file_share_sandbox.json" ] +} diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/include/file_share.h b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/include/file_share.h new file mode 100644 index 00000000..cf1178c6 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/include/file_share.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_FILE_SERVICE_FILE_SHARE +#define APP_FILE_SERVICE_FILE_SHARE + +#include +#include +#include "want.h" + +namespace OHOS { +namespace AppFileService { +using namespace std; + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + int32_t CreateShareFile(const string &uri, uint32_t tokenId, uint32_t flag); + int32_t DeleteShareFile(uint32_t tokenId, vector sharePathList); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ +} // namespace AppFileService +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/src/file_share.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/src/file_share.cpp new file mode 100644 index 00000000..3374bb7c --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_share/src/file_share.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "file_share.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "accesstoken_kit.h" +#include "hap_token_info.h" +#include "log.h" +#include "sandbox_helper.h" +#include "uri.h" + +namespace OHOS { +namespace AppFileService { +#define DIR_MODE (S_IRWXU | S_IXGRP | S_IXOTH) +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) +#define READ_URI_PERMISSION OHOS::AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION +#define WRITE_URI_PERMISSION OHOS::AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION + +enum ShareFileType { + DIR_TYPE = 0, + FILE_TYPE = 1, +}; + +namespace { +const string FILE_SCHEME = "file"; +const string DATA_APP_EL2_PATH = "/data/service/el2/"; +const string SHARE_R_PATH = "/r/"; +const string SHARE_RW_PATH = "/rw/"; +const string SHARE_PATH = "/share/"; +} + +struct FileShareInfo { + string providerBundleName_; + string targetBundleName_; + string providerLowerPath_; + string providerSandboxPath_; + vector sharePath_; + string currentUid_; + ShareFileType type_; +}; + +static int32_t GetTargetInfo(uint32_t tokenId, string &bundleName, string ¤tUid) +{ + Security::AccessToken::HapTokenInfo hapInfo; + int32_t result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo); + if (result != 0) { + LOGE("Failed to get hap token info %{public}d", result); + return result; + } + bundleName = hapInfo.bundleName; + currentUid = to_string(hapInfo.userID); + + int index = hapInfo.instIndex; + if (index != 0) { + bundleName += "_" + to_string(index); + } + return 0; +} + +static void GetProviderInfo(string uriStr, FileShareInfo &info) +{ + Uri uri(uriStr); + info.providerBundleName_ = uri.GetAuthority(); + info.providerSandboxPath_ = uri.GetPath(); +} + +static bool IsExistDir(const string &path) +{ + struct stat buf = {}; + if (stat(path.c_str(), &buf) != 0) { + return false; + } + return S_ISDIR(buf.st_mode); +} + +static bool IsExistFile(const string &path) +{ + struct stat buf = {}; + if (stat(path.c_str(), &buf) != 0) { + LOGE("Get path stat failed, path: %s err %{public}d", path.c_str(), errno); + return false; + } + return S_ISREG(buf.st_mode); +} + +static void GetSharePath(FileShareInfo &info, uint32_t flag) +{ + string shareRPath = DATA_APP_EL2_PATH + info.currentUid_ + SHARE_PATH +info.targetBundleName_ + + SHARE_R_PATH + info.providerBundleName_ + info.providerSandboxPath_; + string shareRWPath = DATA_APP_EL2_PATH + info.currentUid_ + SHARE_PATH +info.targetBundleName_ + + SHARE_RW_PATH + info.providerBundleName_ + info.providerSandboxPath_; + if ((flag & WRITE_URI_PERMISSION) == WRITE_URI_PERMISSION) { + info.sharePath_.push_back(shareRWPath); + info.sharePath_.push_back(shareRPath); + } else if ((flag & READ_URI_PERMISSION) == READ_URI_PERMISSION) { + info.sharePath_.push_back(shareRPath); + } +} + +static int32_t GetShareFileType(FileShareInfo &info) +{ + if (IsExistFile(info.providerLowerPath_)) { + info.type_ = ShareFileType::FILE_TYPE; + return 0; + } else if (IsExistDir(info.providerLowerPath_)) { + info.type_ = ShareFileType::DIR_TYPE; + return 0; + } + return -ENOENT; +} + +static int32_t GetFileShareInfo(const string &uri, uint32_t tokenId, uint32_t flag, FileShareInfo &info) +{ + int32_t ret = 0; + ret = GetTargetInfo(tokenId, info.targetBundleName_, info.currentUid_); + if (ret != 0) { + LOGE("Failed to get target info %{public}d", ret); + return ret; + } + + GetProviderInfo(uri, info); + + ret = SandboxHelper::GetPhysicalPath(uri, info.currentUid_, info.providerLowerPath_); + if (ret != 0) { + LOGE("Failed to get lower path %{public}d", ret); + return ret; + } + + ret = GetShareFileType(info); + if (ret != 0) { + LOGE("Failed to get share file type %{public}d", ret); + return ret; + } + + GetSharePath(info, flag); + return 0; +} + +static bool MakeDir(const string &path) +{ + string::size_type index = 0; + string subPath; + do { + index = path.find('/', index + 1); + if (index == string::npos) { + subPath = path; + } else { + subPath = path.substr(0, index); + } + + if (access(subPath.c_str(), 0) != 0) { + if (mkdir(subPath.c_str(), DIR_MODE) != 0) { + LOGE("Failed to make dir with %{public}d", errno); + return false; + } + } + } while (index != string::npos); + + return true; +} + +static void DeleteExistShareFile(const string &path) +{ + if (access(path.c_str(), F_OK) == 0) { + if (umount2(path.c_str(), MNT_DETACH) != 0) { + LOGE("Umount failed with %{public}d", errno); + } + remove(path.c_str()); + } +} + +static int32_t PreparePreShareDir(FileShareInfo &info) +{ + if (!SandboxHelper::CheckValidPath(info.providerLowerPath_)) { + LOGE("Invalid share path with %{private}s", info.providerLowerPath_.c_str()); + return -EINVAL; + } + + for (size_t i = 0; i < info.sharePath_.size(); i++) { + if (access(info.sharePath_[i].c_str(), F_OK) != 0) { + string sharePathDir = info.sharePath_[i]; + size_t posLast = info.sharePath_[i].find_last_of("/"); + sharePathDir = info.sharePath_[i].substr(0, posLast); + if (!MakeDir(sharePathDir.c_str())) { + LOGE("Make dir failed with %{public}d", errno); + return -errno; + } + } else { + DeleteExistShareFile(info.sharePath_[i]); + } + } + return 0; +} + +int32_t CreateShareFile(const string &uri, uint32_t tokenId, uint32_t flag) +{ + FileShareInfo info; + string decodeUri = SandboxHelper::Decode(uri); + LOGD("CreateShareFile begin with uri %{private}s decodeUri %{private}s", + uri.c_str(), decodeUri.c_str()); + int32_t ret = GetFileShareInfo(decodeUri, tokenId, flag, info); + if (ret != 0) { + LOGE("Failed to get FileShareInfo with %{public}d", ret); + return ret; + } + + if ((ret = PreparePreShareDir(info)) != 0) { + LOGE("PreparePreShareDir failed"); + return ret; + } + + for (size_t i = 0; i < info.sharePath_.size(); i++) { + if (info.type_ == ShareFileType::FILE_TYPE) { + if ((ret = creat(info.sharePath_[i].c_str(), FILE_MODE)) < 0) { + LOGE("Create file failed with %{public}d", errno); + return -errno; + } + close(ret); + } else { + LOGE("Invalid argument not support dir to share"); + return -EINVAL; + } + + if (mount(info.providerLowerPath_.c_str(), info.sharePath_[i].c_str(), + nullptr, MS_BIND, nullptr) != 0) { + LOGE("Mount failed with %{public}d", errno); + return -errno; + } + } + LOGI("Create Share File Successfully!"); + return 0; +} + +static void UmountDelUris(vector sharePathList, string currentUid, string bundleNameSelf) +{ + for (size_t i = 0; i < sharePathList.size(); i++) { + Uri uri(SandboxHelper::Decode(sharePathList[i])); + string path = uri.GetPath(); + string bundleName = uri.GetAuthority(); + string delRPath = DATA_APP_EL2_PATH + currentUid + SHARE_PATH + bundleNameSelf + SHARE_R_PATH + + bundleName + path; + string delRWPath = DATA_APP_EL2_PATH + currentUid + SHARE_PATH + bundleNameSelf + SHARE_RW_PATH + + bundleName + path; + if (access(delRPath.c_str(), F_OK) == 0) { + if (umount2(delRPath.c_str(), MNT_DETACH) != 0) { + LOGE("UmountdelRPath, umount failed with %{public}d", errno); + } + remove(delRPath.c_str()); + } + if (access(delRWPath.c_str(), F_OK) == 0) { + if (umount2(delRWPath.c_str(), MNT_DETACH) != 0) { + LOGE("UmountdelRWPath, umount failed with %{public}d", errno); + } + remove(delRWPath.c_str()); + } + } +} + +int32_t DeleteShareFile(uint32_t tokenId, vector sharePathList) +{ + string bundleName, currentUid; + int32_t ret = GetTargetInfo(tokenId, bundleName, currentUid); + if (ret != 0) { + LOGE("Failed to delete share file %{public}d", -EINVAL); + return -EINVAL; + } + UmountDelUris(sharePathList, currentUid, bundleName); + + LOGI("Delete Share File Successfully!"); + return 0; +} +} // namespace AppFileService +} // namespace OHOS \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include/file_uri.h b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include/file_uri.h new file mode 100644 index 00000000..eb76514c --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include/file_uri.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_FILE_SERVICE_FILE_URI_FILE_URI_H +#define APP_FILE_SERVICE_FILE_URI_FILE_URI_H + +#include + +#include "uri.h" +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { +class FileUri { +public: + std::string GetName(); + std::string GetPath(); + std::string ToString(); + + explicit FileUri(const std::string &uriOrPath); + ~FileUri() = default; +private: + Uri uri_; +}; +} // ModuleFileUri +} // namespace AppFileService +} // namespace OHOS +#endif // APP_FILE_SERVICE_FILE_URI_FILE_URI_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/src/file_uri.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/src/file_uri.cpp new file mode 100644 index 00000000..d30bc0a5 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/src/file_uri.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "file_uri.h" + +#include + +#include "uri.h" + +#include "common_func.h" +#include "log.h" + +using namespace std; +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { +const std::string PATH_SHARE = "/data/storage/el2/share"; +const std::string MODE_RW = "/rw/"; +const std::string MODE_R = "/r/"; +const std::string FILE_SCHEME_PREFIX = "file://"; +string FileUri::GetName() +{ + string sandboxPath = uri_.GetPath(); + size_t posLast = sandboxPath.find_last_of("/"); + if (posLast == string::npos) { + return sandboxPath; + } + + if (posLast == sandboxPath.size()) { + return ""; + } + + return sandboxPath.substr(posLast + 1); +} + +string FileUri::GetPath() +{ + string sandboxPath = uri_.GetPath(); + string realPath = sandboxPath; + string providerBundleName = uri_.GetAuthority(); + string targetBundleName = CommonFunc::GetSelfBundleName(); + if (CommonFunc::CheckPublicDirPath(realPath) || + ((targetBundleName != providerBundleName) && (providerBundleName != ""))) { + realPath = PATH_SHARE + MODE_RW + providerBundleName + sandboxPath; + if (access(realPath.c_str(), F_OK) != 0) { + realPath = PATH_SHARE + MODE_R + providerBundleName + sandboxPath; + } + } + + return realPath; +} + +string FileUri::ToString() +{ + return uri_.ToString(); +} + +FileUri::FileUri(const string &uriOrPath): uri_( + (uriOrPath.find(FILE_SCHEME_PREFIX) == 0) ? uriOrPath : CommonFunc::GetUriFromPath(uriOrPath) +) +{} +} +} // namespace AppFileService +} // namespace OHOS \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include/remote_file_share.h b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include/remote_file_share.h new file mode 100644 index 00000000..e94a6ed9 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include/remote_file_share.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef REMOTE_FILE_SHARE_H +#define REMOTE_FILE_SHARE_H + +#include + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +namespace { + const std::string SHARE_ALL_DEVICE = "0"; +} + +struct HmdfsUriInfo { + std::string uriStr; + size_t fileSize; +}; + +class RemoteFileShare { +public: + RemoteFileShare() {} + static int CreateSharePath(const int &fd, std::string &sharePath, + const int &userId, const std::string &deviceId = SHARE_ALL_DEVICE); + static int32_t GetDfsUriFromLocal(const std::string &uriStr, const int32_t &userId, struct HmdfsUriInfo &hui); + ~RemoteFileShare() {} +}; +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/src/remote_file_share.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/src/remote_file_share.cpp new file mode 100644 index 00000000..9a8d5e41 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/src/remote_file_share.cpp @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "remote_file_share.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "sandbox_helper.h" +#include "securec.h" +#include "uri.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +namespace { + const int HMDFS_CID_SIZE = 64; + const int USER_ID_INIT = 100; + const unsigned HMDFS_IOC = 0xf2; + const std::string FILE_SCHEME = "file"; + const std::string DISTRIBUTED_DIR_PATH = "/data/storage/el2/distributedfiles"; + const std::string DST_PATH_HEAD = "/data/service/el2/"; + const std::string DST_PATH_MID = "/hmdfs/account/data/"; + const std::string SHAER_PATH_HEAD = "/mnt/hmdfs/"; + const std::string SHAER_PATH_MID = "/account/merge_view/services/"; + const std::string LOWER_SHARE_PATH_HEAD = "/mnt/hmdfs/"; + const std::string LOWER_SHARE_PATH_MID = "/account/device_view/local/services/"; + const std::string SHARE_PATH_DIR = "/.share"; + const std::string REMOTE_SHARE_PATH_DIR = "/.remote_share"; +} + +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct HmdfsShareControl) +#define HMDFS_IOC_GET_DST_PATH _IOR(HMDFS_IOC, 3, unsigned int) + +struct HmdfsShareControl { + int fd; + char deviceId[HMDFS_CID_SIZE]; +}; + +struct HmdfsDstInfo { + uint64_t localLen; + uint64_t localPathIndex; + uint64_t distributedLen; + uint64_t distributedPathIndex; + uint64_t bundleNameLen; + uint64_t bundleNameIndex; + uint64_t size; +}; + +static std::string GetProcessName() +{ + char pthreadName[PATH_MAX]; + int ret = pthread_getname_np(pthread_self(), pthreadName, sizeof(pthreadName)); + if (ret != 0) { + LOGE("RemoteFileShare::GetProcessName, pthread_getname_np failed with %{public}d", errno); + return ""; + } + std::string pthreadNameStr = pthreadName; + LOGI("RemoteFileShare::GetProcessName, thread name is %{public}s", pthreadNameStr.c_str()); + return pthreadNameStr; +} + +static std::string GetFileName(const int &fd) +{ + char buf[PATH_MAX] = {'\0'}; + char filePath[PATH_MAX] = {'\0'}; + + int ret = snprintf_s(buf, sizeof(buf), sizeof(buf), "/proc/self/fd/%d", fd); + if (ret < 0) { + LOGE("RemoteFileShare::GetFileName, snprintf failed with %{public}d", errno); + return ""; + } + + ret = readlink(buf, filePath, PATH_MAX); + if (ret < 0 || ret >= PATH_MAX) { + LOGE("RemoteFileShare::GetFileName, readlink failed with %{public}d", errno); + return ""; + } + + std::string fileName = filePath; + std::size_t firstSlash = fileName.rfind("/"); + if (firstSlash == fileName.npos) { + LOGE("RemoteFileShare::GetFileName, get error path with %{public}s", fileName.c_str()); + return ""; + } + fileName = fileName.substr(firstSlash + 1, fileName.size() - firstSlash); + return fileName; +} + +static int CreateShareDir(const std::string &path) +{ + if (access(path.c_str(), F_OK) != 0) { + int ret = mkdir(path.c_str(), S_IRWXU); + if (ret != 0) { + LOGE("RemoteFileShare::CreateShareDir, make dir failed with %{public}d", errno); + return errno; + } + } + return 0; +} + +static std::string GetSharePath(const int &userId, const std::string &packageName) +{ + return SHAER_PATH_HEAD + std::to_string(userId) + SHAER_PATH_MID + packageName; +} + +static std::string GetLowerSharePath(const int &userId, const std::string &packageName) +{ + return LOWER_SHARE_PATH_HEAD + std::to_string(userId) + LOWER_SHARE_PATH_MID + packageName; +} + +static bool DeleteShareDir(const std::string &PACKAGE_PATH, const std::string &SHARE_PATH) +{ + bool result = true; + if (access(SHARE_PATH.c_str(), F_OK) == 0) { + int ret = rmdir(SHARE_PATH.c_str()); + if (ret != 0) { + LOGE("RemoteFileShare::DeleteShareDir, delete dir failed with %{public}d", errno); + result = false; + } else { + LOGI("RemoteFileShare::DeleteShareDir, delete %{public}s path successfully", SHARE_PATH.c_str()); + } + } + if (access(PACKAGE_PATH.c_str(), F_OK) == 0) { + int ret = rmdir(PACKAGE_PATH.c_str()); + if (ret != 0) { + LOGE("RemoteFileShare::DeleteShareDir, delete dir failed with %{public}d", errno); + result = false; + } else { + LOGI("RemoteFileShare::DeleteShareDir, delete %{public}s path successfully", PACKAGE_PATH.c_str()); + } + } + return result; +} + +static int CreateShareFile(struct HmdfsShareControl &shareControl, const char* file, + const std::string &deviceId) +{ + int32_t dirFd = open(file, O_RDONLY); + if (dirFd < 0) { + LOGE("RemoteFileShare::CreateShareFile, open share path failed with %{public}d", errno); + return errno; + } + + memset_s(shareControl.deviceId, HMDFS_CID_SIZE, '\0', HMDFS_CID_SIZE); + if (memcpy_s(shareControl.deviceId, HMDFS_CID_SIZE, deviceId.c_str(), deviceId.size()) != 0) { + LOGE("RemoteFileShare::CreateShareFile, memcpy_s failed with %{public}d", errno); + close(dirFd); + return errno; + } + + if (ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &shareControl) < 0) { + LOGE("RemoteFileShare::CreateShareFile, ioctl failed with %{public}d", errno); + close(dirFd); + return errno; + } + close(dirFd); + return 0; +} + +static int CheckInputValidity(const int &fd, const int &userId, const std::string &deviceId) +{ + return (fd < 0) || (userId < USER_ID_INIT) || (deviceId != SHARE_ALL_DEVICE && + deviceId.size() != HMDFS_CID_SIZE); +} + +int RemoteFileShare::CreateSharePath(const int &fd, std::string &sharePath, + const int &userId, const std::string &deviceId) +{ + struct HmdfsShareControl shareControl; + shareControl.fd = fd; + + if (CheckInputValidity(fd, userId, deviceId) != 0) { + LOGE("RemoteFileShare::CreateSharePath, invalid argument with %{public}d", EINVAL); + return EINVAL; + } + + const std::string processName = GetProcessName(); + if (processName == "") { + LOGE("RemoteFileShare::CreateSharePath, GetProcessName failed with %{public}d", errno); + return errno; + } + + const std::string PACKAGE_PATH = GetLowerSharePath(userId, processName); + const std::string LOWER_SHARE_PATH = PACKAGE_PATH + SHARE_PATH_DIR; + if (CreateShareDir(PACKAGE_PATH) != 0) + return errno; + if (CreateShareDir(LOWER_SHARE_PATH) != 0) { + DeleteShareDir(PACKAGE_PATH, LOWER_SHARE_PATH); + return errno; + } + + const std::string SHARE_PATH = GetSharePath(userId, processName) + SHARE_PATH_DIR; + char realPath[PATH_MAX] = {'\0'}; + if (!realpath(SHARE_PATH.c_str(), realPath)) { + LOGE("RemoteFileShare::CreateSharePath, realpath failed with %{public}d", errno); + DeleteShareDir(PACKAGE_PATH, LOWER_SHARE_PATH); + return errno; + } + + std::string file_name = GetFileName(shareControl.fd); + if (file_name == "") { + LOGE("RemoteFileShare::CreateSharePath, get error file name"); + DeleteShareDir(PACKAGE_PATH, LOWER_SHARE_PATH); + return EBADF; + } + sharePath = SHARE_PATH + "/" + file_name; + + if (CreateShareFile(shareControl, realPath, deviceId) != 0) { + LOGE("RemoteFileShare::CreateSharePath, create share file failed with %{public}d", errno); + /* When the file is exist, we should not delete the dictionary */ + if (errno == EEXIST) { + return 0; + } + sharePath = ""; + DeleteShareDir(PACKAGE_PATH, LOWER_SHARE_PATH); + return errno; + } + LOGI("RemoteFileShare::CreateSharePath, create %{public}s successfully", sharePath.c_str()); + return 0; +} + +static int GetDistributedPath(Uri &uri, const int &userId, std::string &distributedPath) +{ + distributedPath = DST_PATH_HEAD + std::to_string(userId) + DST_PATH_MID + + uri.GetAuthority() + REMOTE_SHARE_PATH_DIR + uri.GetPath(); + if (distributedPath.size() >= PATH_MAX) { + return -EINVAL; + } + + return 0; +} + +static bool IsValidPath(const std::string &path) +{ + if (path.find("/./") != std::string::npos || + path.find("/../") != std::string::npos) { + return false; + } + return true; +} + +static std::string GetPhysicalPath(Uri &uri, const std::string &userId) +{ + std::string sandboxPath = uri.GetPath(); + if (!IsValidPath(sandboxPath) || uri.GetScheme() != FILE_SCHEME) { + LOGE("Sandbox path from uri is error with %{public}s", sandboxPath.c_str()); + return ""; + } + + std::string physicalPath = ""; + int ret = SandboxHelper::GetPhysicalPath(uri.ToString(), userId, physicalPath); + if (ret != 0) { + LOGE("Get physical path failed with %{public}d", ret); + return ""; + } + return physicalPath; +} + +static void InitHmdfsInfo(struct HmdfsDstInfo &hdi, const std::string &physicalPath, + const std::string &distributedPath, const std::string &bundleName) +{ + hdi.localLen = physicalPath.size() + 1; + hdi.localPathIndex = (uint64_t)(physicalPath.c_str()); + + hdi.distributedLen = distributedPath.size() + 1; + hdi.distributedPathIndex = (uint64_t)(distributedPath.c_str()); + + hdi.bundleNameLen = bundleName.size() + 1; + hdi.bundleNameIndex = (uint64_t)(bundleName.c_str()); + + hdi.size = (uint64_t)&hdi.size; +} + +static void SetHmdfsUriInfo(struct HmdfsUriInfo &hdi, Uri &uri, uint64_t fileSize) +{ + std::string bundleName = uri.GetAuthority(); + std::string path = uri.GetPath(); + + hdi.uriStr = SandboxHelper::Encode(FILE_SCHEME + "://" + bundleName + DISTRIBUTED_DIR_PATH + + REMOTE_SHARE_PATH_DIR + path); + hdi.fileSize = fileSize; + return; +} + +int32_t RemoteFileShare::GetDfsUriFromLocal(const std::string &uriStr, const int32_t &userId, + struct HmdfsUriInfo &hui) +{ + Uri uri(SandboxHelper::Decode(uriStr)); + LOGD("GetDfsUriFromLocal begin with uri:%{private}s, decode uri:%{private}s", + uriStr.c_str(), uri.ToString().c_str()); + std::string physicalPath = GetPhysicalPath(uri, std::to_string(userId)); + if (physicalPath == "") { + LOGE("Failed to get physical path"); + return -EINVAL; + } + + std::string distributedPath; + int ret = GetDistributedPath(uri, userId, distributedPath); + if (ret != 0) { + LOGE("Path is too long with %{public}d", ret); + return ret; + } + + struct HmdfsDstInfo hdi; + std::string bundleName = uri.GetAuthority(); + LOGD("PhysicalPath: %{private}s DistributedPath: %{private}s BundleName: %{private}s", + physicalPath.c_str(), distributedPath.c_str(), bundleName.c_str()); + InitHmdfsInfo(hdi, physicalPath, distributedPath, bundleName); + + std::string ioctlDir = SHAER_PATH_HEAD + std::to_string(userId) + SHAER_PATH_MID; + int32_t dirFd = open(ioctlDir.c_str(), O_RDONLY); + if (dirFd < 0) { + LOGE("Open share path failed with %{public}d", errno); + return errno; + } + + ret = ioctl(dirFd, HMDFS_IOC_GET_DST_PATH, &hdi); + if (ret != 0) { + LOGE("Ioctl failed with %{public}d", errno); + close(dirFd); + return -errno; + } + + close(dirFd); + SetHmdfsUriInfo(hui, uri, hdi.size); + LOGD("GetDfsUriFromLocal successfully with %{private}s", hui.uriStr.c_str()); + return 0; +} +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/BUILD.gn new file mode 100644 index 00000000..81108577 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/BUILD.gn @@ -0,0 +1,139 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/app_file_service.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +ohos_shared_library("remotefileshare") { + include_dirs = [ + "${path_napi}/interfaces/kits", + "//third_party/bounds_checking_function/include", + ] + + sources = [ + "remote_file_share/remotefileshare_n_exporter.cpp", + "remote_file_share/remotefileshare_napi.cpp", + ] + + deps = [ "${third_party_path}/bounds_checking_function:libsec_shared" ] + + external_deps = [ + "file_api:filemgmt_libhilog", + "file_api:filemgmt_libn", + "hilog:libhilog", + "napi:ace_napi", + ] + + relative_install_dir = "module" + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_shared_library("fileshare") { + include_dirs = [ + ".", + "../../common/include", + ] + + sources = [ + "file_share/fileshare_n_exporter.cpp", + "file_share/grant_uri_permission.cpp", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:abilitykit_native", + "access_token:libtokenid_sdk", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "data_share:datashare_common", + "data_share:datashare_consumer", + "file_api:filemgmt_libhilog", + "file_api:filemgmt_libn", + "file_api:remote_uri_native", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + ] + + relative_install_dir = "module" + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_shared_library("fileuri") { + include_dirs = [ + ".", + "../../common/include", + ] + + sources = [ + "../../common/src/common_func.cpp", + "../../common/src/sandbox_helper.cpp", + "file_uri/file_uri_n_exporter.cpp", + "file_uri/get_uri_from_path.cpp", + ] + + external_deps = [ + "ability_runtime:abilitykit_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "file_api:filemgmt_libhilog", + "file_api:filemgmt_libn", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "samgr:samgr_proxy", + ] + + relative_install_dir = "module/file" + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_shared_library("backup") { + relative_install_dir = "module/file" + subsystem_name = "filemanagement" + part_name = "app_file_service" + + include_dirs = [ "${path_napi}/interfaces/kits" ] + + sources = [ + "${path_backup_js}/backup/local_capabilities.cpp", + "${path_backup_js}/backup/module.cpp", + "${path_backup_js}/backup/prop_n_exporter.cpp", + "${path_backup_js}/backup/session_backup_n_exporter.cpp", + "${path_backup_js}/backup/session_restore_n_exporter.cpp", + ] + + deps = [ + "${path_backup}/interfaces/inner_api/native/backup_kit_inner:backup_kit_inner", + "${path_backup}/utils:backup_utils", + "${path_jsoncpp}:jsoncpp", + ] + + external_deps = [ + "c_utils:utils", + "file_api:filemgmt_libhilog", + "file_api:filemgmt_libn", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + ] +} diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/general_callbacks.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/general_callbacks.h new file mode 100644 index 00000000..6bde169b --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/general_callbacks.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_GENERAL_CALLBACKS_H +#define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_GENERAL_CALLBACKS_H + +#include +#include +#include + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::Backup { +class GeneralCallbacks { +public: + GeneralCallbacks(const napi_env &env, const LibN::NVal &thisPtr, const LibN::NVal &jsCallbacks) + : onFileReady(env, thisPtr, jsCallbacks.GetProp("onFileReady")), + onBundleBegin(env, thisPtr, jsCallbacks.GetProp("onBundleBegin")), + onBundleEnd(env, thisPtr, jsCallbacks.GetProp("onBundleEnd")), + onAllBundlesEnd(env, thisPtr, jsCallbacks.GetProp("onAllBundlesEnd")), + onBackupServiceDied(env, thisPtr, jsCallbacks.GetProp("onBackupServiceDied")) {}; + +public: + LibN::NAsyncWorkCallback onFileReady; + LibN::NAsyncWorkCallback onBundleBegin; + LibN::NAsyncWorkCallback onBundleEnd; + LibN::NAsyncWorkCallback onAllBundlesEnd; + LibN::NAsyncWorkCallback onBackupServiceDied; +}; +} // namespace OHOS::FileManagement::Backup +#endif // INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_GENERAL_CALLBACKS_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.cpp new file mode 100644 index 00000000..9c8ea23e --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "local_capabilities.h" + +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" +#include "service_proxy.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace LibN; + +napi_value LocalCapabilities::Async(napi_env env, napi_callback_info info) +{ + HILOGI("called LocalCapabilities::Async begin"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto fd = make_shared(); + auto cbExec = [fd]() -> NError { + HILOGI("called LocalCapabilities::Async cbExec"); + auto proxy = ServiceProxy::GetInstance(); + if (!proxy) { + HILOGI("called LocalCapabilities::Async cbExec, failed to get proxy"); + return NError(errno); + } + *fd = proxy->GetLocalCapabilities(); + return NError(ERRNO_NOERR); + }; + auto cbCompl = [fd](napi_env env, NError err) -> NVal { + if (err) { + return {env, err.GetNapiErr(env)}; + } + NVal obj = NVal::CreateObject(env); + obj.AddProp({NVal::DeclareNapiProperty("fd", NVal::CreateInt32(env, fd->Release()).val_)}); + return {obj}; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ZERO) { + HILOGI("called LocalCapabilities::Async::promise"); + return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_LOCALCAPABILITIES_NAME, cbExec, cbCompl).val_; + } else { + HILOGI("called LocalCapabilities::Async::callback"); + NVal cb(env, funcArg[NARG_POS::FIRST]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_LOCALCAPABILITIES_NAME, cbExec, cbCompl).val_; + } +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.h new file mode 100644 index 00000000..716b5d3d --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/local_capabilities.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_LOCAL_CAPABILITIES_H +#define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_LOCAL_CAPABILITIES_H + +#include +#include + +namespace OHOS::FileManagement::Backup { +class LocalCapabilities final { +public: + static napi_value Async(napi_env env, napi_callback_info info); +}; + +const std::string PROCEDURE_LOCALCAPABILITIES_NAME = "getLocalCapalities"; +} // namespace OHOS::FileManagement::Backup +#endif // INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_LOCAL_CAPABILITIES_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/module.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/module.cpp new file mode 100644 index 00000000..6a0cc1ec --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/module.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "filemgmt_libhilog.h" +#include "filemgmt_libn.h" +#include "prop_n_exporter.h" +#include "session_backup_n_exporter.h" +#include "session_restore_n_exporter.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace LibN; + +static napi_value Export(napi_env env, napi_value exports) +{ + std::vector> products; + products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); + products.emplace_back(make_unique(env, exports)); + for (auto &&product : products) { + if (!product->Export()) { + HILOGE("INNER BUG. Failed to export class %{public}s for module backup", product->GetClassName().c_str()); + return nullptr; + } else { + HILOGI("Class %{public}s for module fileio has been exported", product->GetClassName().c_str()); + } + } + return exports; +} + +NAPI_MODULE(backup, Export) +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.cpp new file mode 100644 index 00000000..572a46db --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "prop_n_exporter.h" + +#include "local_capabilities.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace LibN; + +bool PropNExporter::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("getLocalCapabilities", LocalCapabilities::Async), + }); +} + +string PropNExporter::GetClassName() +{ + return PropNExporter::className; +} + +PropNExporter::PropNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +PropNExporter::~PropNExporter() {} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.h new file mode 100644 index 00000000..defb4c78 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/prop_n_exporter.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_PROP_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_PROP_N_EXPORTER_H + +#include + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::Backup { +class PropNExporter final : public LibN::NExporter { +public: + inline static const std::string className = "LocalCapabilities"; + + bool Export() override; + std::string GetClassName() override; + + PropNExporter(napi_env env, napi_value exports); + ~PropNExporter() override; +}; +} // namespace OHOS::FileManagement::Backup +#endif // INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_PROP_N_EXPORTER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.cpp new file mode 100644 index 00000000..e3a5a130 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "session_backup_n_exporter.h" + +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_file.h" +#include "b_resources/b_constants.h" +#include "b_session_backup.h" +#include "backup_kit_inner.h" +#include "directory_ex.h" +#include "filemgmt_libhilog.h" +#include "general_callbacks.h" +#include "service_proxy.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace LibN; + +struct BackupEntity { + unique_ptr session; + shared_ptr callbacks; +}; + +static void OnFileReady(weak_ptr pCallbacks, const BFileInfo &fileInfo, UniqueFd fd) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onFileReady has already been released"); + return; + } + if (!bool(callbacks->onFileReady)) { + HILOGI("callback function onFileReady is undefined"); + return; + } + + auto cbCompl = [bundleName {fileInfo.owner}, fileName {fileInfo.fileName}, + fd {make_shared(fd.Release())}](napi_env env, NError err) -> NVal { + if (err) { + return {env, err.GetNapiErr(env)}; + } + NVal obj = NVal::CreateObject(env); + obj.AddProp({NVal::DeclareNapiProperty("bundleName", NVal::CreateUTF8String(env, bundleName).val_), + NVal::DeclareNapiProperty("uri", NVal::CreateUTF8String(env, fileName).val_), + NVal::DeclareNapiProperty("fd", NVal::CreateInt32(env, fd->Release()).val_)}); + + return {obj}; + }; + + callbacks->onFileReady.ThreadSafeSchedule(cbCompl); +} + +static void onBundleBegin(weak_ptr pCallbacks, ErrCode err, const BundleName name) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onBundleBegin has already been released"); + return; + } + if (!bool(callbacks->onBundleBegin)) { + HILOGI("callback function onBundleBegin is undefined"); + return; + } + + auto cbCompl = [name {name}](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, name); + }; + + callbacks->onBundleBegin.ThreadSafeSchedule(cbCompl); +} + +static void onBundleEnd(weak_ptr pCallbacks, ErrCode err, const BundleName name) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onBundleEnd has already been released"); + return; + } + if (!bool(callbacks->onBundleEnd)) { + HILOGI("callback function onBundleEnd is undefined"); + return; + } + + auto cbCompl = [name {name}](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, name); + }; + + callbacks->onBundleEnd.ThreadSafeSchedule(cbCompl); +} + +static void onAllBundlesEnd(weak_ptr pCallbacks, ErrCode err) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onAllBundlesEnd has already been released"); + return; + } + if (!bool(callbacks->onAllBundlesEnd)) { + HILOGI("callback function onAllBundlesEnd is undefined"); + return; + } + + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + callbacks->onAllBundlesEnd.ThreadSafeSchedule(cbCompl); +} + +static void OnBackupServiceDied(weak_ptr pCallbacks) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("js callback function onBackupServiceDied has already been released"); + return; + } + if (!bool(callbacks->onBackupServiceDied)) { + HILOGI("callback function onBackupServiceDied is undefined"); + return; + } + + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + callbacks->onBackupServiceDied.ThreadSafeSchedule(cbCompl); +} + +napi_value SessionBackupNExporter::Constructor(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionBackup::Constructor begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal callbacks(env, funcArg[NARG_POS::FIRST]); + if (!callbacks.TypeIs(napi_object)) { + HILOGE("First argument is not an object."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal ptr(env, funcArg.GetThisVar()); + auto backupEntity = std::make_unique(); + backupEntity->callbacks = make_shared(env, ptr, callbacks); + backupEntity->session = BSessionBackup::Init(BSessionBackup::Callbacks { + .onFileReady = bind(OnFileReady, backupEntity->callbacks, placeholders::_1, placeholders::_2), + .onBundleStarted = bind(onBundleBegin, backupEntity->callbacks, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(onBundleEnd, backupEntity->callbacks, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(onAllBundlesEnd, backupEntity->callbacks, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, backupEntity->callbacks)}); + if (!backupEntity->session) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to init backup").GetCode()).ThrowErr(env); + return nullptr; + } + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(backupEntity))) { + HILOGE("Failed to set BackupEntity entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + HILOGI("called SessionBackup::Constructor end"); + return funcArg.GetThisVar(); +} + +napi_value SessionBackupNExporter::AppendBundles(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionBackup::AppendBundles begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal jsBundles(env, funcArg[NARG_POS::FIRST]); + auto [succ, bundles, ignore] = jsBundles.ToStringArray(); + if (!succ) { + HILOGE("First argument is not bundles array."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto backupEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(backupEntity && backupEntity->session)) { + HILOGE("Failed to get backupSession entity."); + NError(EPERM).ThrowErr(env); + return nullptr; + } + + auto cbExec = [session {backupEntity->session.get()}, bundles {bundles}]() -> NError { + if (!session) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "backup session is nullptr").GetCode()); + } + return NError(session->AppendBundles(bundles)); + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + HILOGE("Called SessionBackup::AppendBundles end."); + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_; + } +} + +bool SessionBackupNExporter::Export() +{ + HILOGI("called SessionBackupNExporter::Export begin"); + vector props = {NVal::DeclareNapiFunction("appendBundles", AppendBundles)}; + + auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); + if (!succ) { + HILOGE("Failed to define class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Failed to save class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + HILOGI("called SessionBackupNExporter::Export end"); + return exports_.AddProp(className, classValue); +} + +string SessionBackupNExporter::GetClassName() +{ + return SessionBackupNExporter::className; +} + +SessionBackupNExporter::SessionBackupNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +SessionBackupNExporter::~SessionBackupNExporter() {} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.h new file mode 100644 index 00000000..afa3c96b --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_backup_n_exporter.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_BACKUP_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_BACKUP_N_EXPORTER_H + +#include "n_exporter.h" + +namespace OHOS::FileManagement::Backup { +class SessionBackupNExporter final : public LibN::NExporter { +public: + inline static const std::string className = "SessionBackup"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + static napi_value AppendBundles(napi_env env, napi_callback_info cbinfo); + + SessionBackupNExporter(napi_env env, napi_value exports); + ~SessionBackupNExporter() override; +}; +} // namespace OHOS::FileManagement::Backup +#endif // INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_BACKUP_N_EXPORTER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.cpp new file mode 100644 index 00000000..0f359306 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.cpp @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "session_restore_n_exporter.h" + +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_dir.h" +#include "b_filesystem/b_file.h" +#include "b_resources/b_constants.h" +#include "b_session_restore.h" +#include "backup_kit_inner.h" +#include "filemgmt_libhilog.h" +#include "general_callbacks.h" +#include "service_proxy.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +using namespace LibN; + +struct RestoreEntity { + unique_ptr session; + shared_ptr callbacks; +}; + +static void OnFileReady(weak_ptr pCallbacks, const BFileInfo &fileInfo, UniqueFd fd) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onFileReady has already been released"); + return; + } + if (!bool(callbacks->onFileReady)) { + HILOGI("callback function onFileReady is undefined"); + return; + } + + auto cbCompl = [bundleName {fileInfo.owner}, fileName {fileInfo.fileName}, + fd {make_shared(fd.Release())}](napi_env env, NError err) -> NVal { + if (err) { + return {env, err.GetNapiErr(env)}; + } + NVal obj = NVal::CreateObject(env); + obj.AddProp({NVal::DeclareNapiProperty("bundleName", NVal::CreateUTF8String(env, bundleName).val_), + NVal::DeclareNapiProperty("uri", NVal::CreateUTF8String(env, fileName).val_), + NVal::DeclareNapiProperty("fd", NVal::CreateInt32(env, fd->Release()).val_)}); + + return {obj}; + }; + + callbacks->onFileReady.ThreadSafeSchedule(cbCompl); +} + +static void onBundleBegin(weak_ptr pCallbacks, ErrCode err, const BundleName name) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onBundleBegin has already been released"); + return; + } + if (!bool(callbacks->onBundleBegin)) { + HILOGI("callback function onBundleBegin is undefined"); + return; + } + + auto cbCompl = [name {name}](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, name); + }; + + callbacks->onBundleBegin.ThreadSafeSchedule(cbCompl); +} + +static void onBundleEnd(weak_ptr pCallbacks, ErrCode err, const BundleName name) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onBundleEnd has already been released"); + return; + } + if (!bool(callbacks->onBundleEnd)) { + HILOGI("callback function onBundleEnd is undefined"); + return; + } + + auto cbCompl = [name {name}](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, name); + }; + + callbacks->onBundleEnd.ThreadSafeSchedule(cbCompl); +} + +static void onAllBundlesEnd(weak_ptr pCallbacks, ErrCode err) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("callback function onAllBundlesEnd has already been released"); + return; + } + if (!bool(callbacks->onAllBundlesEnd)) { + HILOGI("callback function onAllBundlesEnd is undefined"); + return; + } + + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + callbacks->onAllBundlesEnd.ThreadSafeSchedule(cbCompl); +} + +static void OnBackupServiceDied(weak_ptr pCallbacks) +{ + if (pCallbacks.expired()) { + HILOGI("callbacks is unbound"); + return; + } + auto callbacks = pCallbacks.lock(); + if (!callbacks) { + HILOGI("js callback function onBackupServiceDied has already been released"); + return; + } + if (!bool(callbacks->onBackupServiceDied)) { + HILOGI("callback function onBackupServiceDied is undefined"); + return; + } + + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + callbacks->onBackupServiceDied.ThreadSafeSchedule(cbCompl); +} + +napi_value SessionRestoreNExporter::Constructor(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionRestore::Constructor begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal callbacks(env, funcArg[NARG_POS::FIRST]); + if (!callbacks.TypeIs(napi_object)) { + HILOGE("First argument is not an object."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal ptr(env, funcArg.GetThisVar()); + auto restoreEntity = std::make_unique(); + restoreEntity->callbacks = make_shared(env, ptr, callbacks); + restoreEntity->session = BSessionRestore::Init(BSessionRestore::Callbacks { + .onFileReady = bind(OnFileReady, restoreEntity->callbacks, placeholders::_1, placeholders::_2), + .onBundleStarted = bind(onBundleBegin, restoreEntity->callbacks, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(onBundleEnd, restoreEntity->callbacks, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(onAllBundlesEnd, restoreEntity->callbacks, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, restoreEntity->callbacks)}); + if (!restoreEntity->session) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to init restore").GetCode()).ThrowErr(env); + return nullptr; + } + if (!NClass::SetEntityFor(env, funcArg.GetThisVar(), move(restoreEntity))) { + HILOGE("Failed to set SessionRestore entity"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + HILOGI("called SessionRestore::Constructor end"); + return funcArg.GetThisVar(); +} + +napi_value SessionRestoreNExporter::AppendBundles(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionRestore::AppendBundles begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal remoteCap(env, funcArg[NARG_POS::FIRST]); + auto [err, fd] = remoteCap.ToInt32(); + if (!err) { + HILOGE("First argument is not remote capabilitily file number."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal jsBundles(env, funcArg[NARG_POS::SECOND]); + auto [succ, bundles, ignore] = jsBundles.ToStringArray(); + if (!succ) { + HILOGE("First argument is not bundles array."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto restoreEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(restoreEntity && restoreEntity->session)) { + HILOGE("Failed to get RestoreSession entity."); + NError(EPERM).ThrowErr(env); + return nullptr; + } + + auto cbExec = [session {restoreEntity->session.get()}, fd {fd}, bundles {bundles}]() -> NError { + if (!session) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode()); + } + return NError(session->AppendBundles(UniqueFd(fd), bundles)); + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + HILOGE("Called SessionRestore::AppendBundles end."); + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::THIRD]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_; + } +} + +static std::tuple, std::unique_ptr> ParseFileMeta(napi_env env, + const NVal &fileMeta) +{ + bool succ = false; + std::unique_ptr bundleName = nullptr; + tie(succ, bundleName, ignore) = fileMeta.GetProp("bundleName").ToUTF8String(); + if (!succ) { + HILOGE("First argument is not have property bundle name."); + return { false, nullptr, nullptr }; + } + + std::unique_ptr fileName = nullptr; + tie(succ, fileName, ignore) = fileMeta.GetProp("uri").ToUTF8String(); + if (!succ) { + HILOGE("First argument is not have property file name."); + return { false, nullptr, nullptr }; + } + + return { true, move(bundleName), move(fileName) }; +} + +napi_value SessionRestoreNExporter::PublishFile(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionRestore::PublishFile begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal fileMeta(env, funcArg[NARG_POS::FIRST]); + if (!fileMeta.TypeIs(napi_object)) { + HILOGE("First arguments is not an object"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, bundleName, fileName] = ParseFileMeta(env, fileMeta); + if (!succ) { + HILOGE("ParseFileMeta failed."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto restoreEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(restoreEntity && restoreEntity->session)) { + HILOGE("Failed to get RestoreSession entity."); + NError(EPERM).ThrowErr(env); + return nullptr; + } + + auto cbExec = [session {restoreEntity->session.get()}, bundleName {string(bundleName.get())}, + fileName {string(fileName.get())}]() -> NError { + if (!session) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode()); + } + BFileInfo fileInfo(bundleName, fileName, 0); + return NError(session->PublishFile(fileInfo)); + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + HILOGE("Called SessionRestore::PublishFile end."); + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_; + } +} + +napi_value SessionRestoreNExporter::GetFileHandle(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("called SessionRestore::GetFileHandle begin"); + NFuncArg funcArg(env, cbinfo); + if (!funcArg.InitArgs(NARG_CNT::ONE, NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + NVal fileMeta(env, funcArg[NARG_POS::FIRST]); + if (!fileMeta.TypeIs(napi_object)) { + HILOGE("First arguments is not an object"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succ, bundleName, fileName] = ParseFileMeta(env, fileMeta); + if (!succ) { + HILOGE("ParseFileMeta failed."); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto restoreEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(restoreEntity && restoreEntity->session)) { + HILOGE("Failed to get RestoreSession entity."); + NError(EPERM).ThrowErr(env); + return nullptr; + } + + auto cbExec = [session {restoreEntity->session.get()}, bundleName {string(bundleName.get())}, + fileName {string(fileName.get())}]() -> NError { + if (!session) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode()); + } + string bundle = bundleName; + string file = fileName; + return NError(session->GetFileHandle(bundle, file)); + }; + auto cbCompl = [](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUndefined(env); + }; + + HILOGE("Called SessionRestore::GetFileHandle end."); + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::ONE) { + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::SECOND]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(className, cbExec, cbCompl).val_; + } +} + +bool SessionRestoreNExporter::Export() +{ + HILOGI("called SessionRestoreNExporter::Export begin"); + vector props = { + NVal::DeclareNapiFunction("appendBundles", AppendBundles), + NVal::DeclareNapiFunction("publishFile", PublishFile), + NVal::DeclareNapiFunction("getFileHandle", GetFileHandle), + }; + + auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); + if (!succ) { + HILOGE("Failed to define class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + succ = NClass::SaveClass(exports_.env_, className, classValue); + if (!succ) { + HILOGE("Failed to save class"); + NError(EIO).ThrowErr(exports_.env_); + return false; + } + + HILOGI("called SessionRestoreNExporter::Export end"); + return exports_.AddProp(className, classValue); +} + +string SessionRestoreNExporter::GetClassName() +{ + return SessionRestoreNExporter::className; +} + +SessionRestoreNExporter::SessionRestoreNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {} + +SessionRestoreNExporter::~SessionRestoreNExporter() {} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.h new file mode 100644 index 00000000..b389b55f --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/backup/session_restore_n_exporter.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_RESTORE_N_EXPORTER_H +#define INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_RESTORE_N_EXPORTER_H + +#include +#include + +#include "filemgmt_libn.h" + +namespace OHOS::FileManagement::Backup { +class SessionRestoreNExporter final : public LibN::NExporter { +public: + inline static const std::string className = "SessionRestore"; + + bool Export() override; + std::string GetClassName() override; + + static napi_value Constructor(napi_env env, napi_callback_info cbinfo); + static napi_value AppendBundles(napi_env env, napi_callback_info cbinfo); + static napi_value PublishFile(napi_env env, napi_callback_info cbinfo); + static napi_value GetFileHandle(napi_env env, napi_callback_info cbinfo); + + SessionRestoreNExporter(napi_env env, napi_value exports); + ~SessionRestoreNExporter() override; +}; +} // namespace OHOS::FileManagement::Backup +#endif // INTERFACES_KITS_JS_SRC_MOD_BACKUP_PROPERTIES_SESSION_RESTORE_N_EXPORTER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.cpp new file mode 100644 index 00000000..a293e305 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "fileshare_n_exporter.h" +#include "grant_uri_permission.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileShare { +/*********************************************** + * Module export and register + ***********************************************/ +napi_value FileShareExport(napi_env env, napi_value exports) +{ + static napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("grantUriPermission", GrantUriPermission::Async), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} + +NAPI_MODULE(fileshare, FileShareExport) +} // namespace ModuleFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.h new file mode 100644 index 00000000..556f62a8 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/fileshare_n_exporter.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILESHARE_N_EXPOTER_H +#define FILESHARE_N_EXPOTER_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileShare { + napi_value FileShareExport(napi_env env, napi_value exports); +} // namespace ModuleFileShare +} // namespace AppFileService +} // namespace OHOS +#endif // FILESHARE_N_EXPOTER_H diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.cpp new file mode 100644 index 00000000..bae9c7c2 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "grant_uri_permission.h" + +#include "ability.h" +#include "datashare_helper.h" +#include "datashare_values_bucket.h" +#include "ipc_skeleton.h" +#include "log.h" +#include "remote_uri.h" +#include "tokenid_kit.h" +#include "want.h" + +using namespace OHOS::DataShare; +using namespace OHOS::FileManagement::LibN; +using namespace OHOS::DistributedFS::ModuleRemoteUri; + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileShare { + enum MediaFileTable { + FILE_TABLE = 0, + PHOTO_TABLE = 1, + AUDIO_TABLE = 2, + }; + + static bool IsAllDigits(string idStr) + { + for (size_t i = 0; i < idStr.size(); i++) { + if (!isdigit(idStr[i])) { + return false; + } + } + return true; + } + + static bool IsSystemApp() + { + uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID(); + return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId); + } + + static string DealWithUriWithName(string str) + { + static uint32_t MEET_COUNT = 6; + uint32_t count = 0; + uint32_t index; + for (index = 0; index < str.length(); index++) { + if (str[index] == '/') { + count++; + } + if (count == MEET_COUNT) { + break; + } + } + if (count == MEET_COUNT) { + str = str.substr(0, index); + } + return str; + } + + static string GetIdFromUri(string uri) + { + uri = DealWithUriWithName(uri); + string rowNum = ""; + size_t pos = uri.rfind('/'); + if (pos != string::npos) { + rowNum = uri.substr(pos + 1); + if (!IsAllDigits(rowNum)) { + rowNum = ""; + } + } + return rowNum; + } + + static string GetModeFromFlag(unsigned int flag) + { + string mode = ""; + if (flag & OHOS::AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION) { + mode += "r"; + } + if (flag & OHOS::AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION) { + mode += "w"; + } + return mode; + } + + static int32_t GetMediaTypeAndApiFromUri(const std::string &uri, bool &isApi10) + { + if (uri.find(MEDIA_FILE_URI_PHOTO_PREFEX) == 0) { + isApi10 = true; + return MediaFileTable::PHOTO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_VIDEO_PREFEX) == 0 || + uri.find(MEDIA_FILE_URI_IMAGE_PREFEX) == 0) { + return MediaFileTable::PHOTO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_AUDIO_PREFEX) == 0) { + isApi10 = true; + return MediaFileTable::AUDIO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_Audio_PREFEX) == 0) { + return MediaFileTable::AUDIO_TABLE; + } else if (uri.find(MEDIA_FILE_URI_FILE_PREFEX) == 0) { + return MediaFileTable::FILE_TABLE; + } + + return MediaFileTable::FILE_TABLE; + } + + static napi_value GetJSArgs(napi_env env, const NFuncArg &funcArg, + DataShareValuesBucket &valuesBucket, bool &isApi10) + { + napi_value result = nullptr; + auto [succPath, path, lenPath] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + LOGE("FileShare::GetJSArgs get path parameter failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + if (!DistributedFS::ModuleRemoteUri::RemoteUri::IsMediaUri(path.get())) { + LOGE("FileShare::GetJSArgs path parameter format error!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto [succBundleName, bundleName, lenBundleName] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!succBundleName) { + LOGE("FileShare::GetJSArgs get bundleName parameter failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + string mode; + if (NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_number)) { + auto [succFlag, flag] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(); + mode = GetModeFromFlag(flag); + } else if (NVal(env, funcArg[NARG_POS::THIRD]).TypeIs(napi_string)) { + auto [succFlag, flag, lenFlag] = NVal(env, funcArg[NARG_POS::THIRD]).ToUTF8String(); + mode = string(flag.get()); + } else { + LOGE("FileShare::GetJSArgs get flag parameter failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + string idStr = GetIdFromUri(string(path.get())); + if (idStr == "") { + LOGE("FileShare::GetJSArgs get fileId parameter failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + int32_t fileId = stoi(idStr); + int32_t filesType = GetMediaTypeAndApiFromUri(string(path.get()), isApi10); + valuesBucket.Put(PERMISSION_FILE_ID, fileId); + valuesBucket.Put(PERMISSION_BUNDLE_NAME, string(bundleName.get())); + valuesBucket.Put(PERMISSION_MODE, mode); + valuesBucket.Put(PERMISSION_TABLE_TYPE, filesType); + napi_get_boolean(env, true, &result); + return result; + } + + static int InsertByDatashare(napi_env env, const DataShareValuesBucket &valuesBucket, bool isApi10) + { + int ret = -1; + std::shared_ptr dataShareHelper = nullptr; + sptr remote = new IRemoteStub(); + if (remote == nullptr) { + LOGE("FileShare::InsertByDatashare get remoteObject failed!"); + return -ENOMEM; + } + + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + if (!dataShareHelper) { + LOGE("FileShare::InsertByDatashare connect to datashare failed!"); + return -E_PERMISSION; + } + string uriStr = MEDIA_GRANT_URI_PERMISSION; + if (isApi10) { + uriStr += MEDIA_API_VERSION_10; + } + + Uri uri(uriStr); + ret = dataShareHelper->Insert(uri, valuesBucket); + if (ret < 0) { + LOGE("FileShare::InsertByDatashare insert failed with error code %{public}d!", ret); + return ret; + } + return ret; + } + + napi_value GrantUriPermission::Async(napi_env env, napi_callback_info info) + { + if (!IsSystemApp()) { + LOGE("FileShare::GrantUriPermission is not System App!"); + NError(E_PERMISSION_SYS).ThrowErr(env); + return nullptr; + } + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::THREE, NARG_CNT::FOUR)) { + LOGE("FileShare::GrantUriPermission GetJSArgsForGrantUriPermission Number of arguments unmatched!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + OHOS::DataShare::DataShareValuesBucket valuesBucket; + bool isApi10 = false; + bool result = GetJSArgs(env, funcArg, valuesBucket, isApi10); + if (!result) { + LOGE("FileShare::GrantUriPermission GetJSArgsForGrantUriPermission failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto cbExec = [valuesBucket, isApi10, env]() -> NError { + int ret = InsertByDatashare(env, valuesBucket, isApi10); + if (ret < 0) { + LOGE("FileShare::GrantUriPermission InsertByDatashare failed!"); + return NError(-ret); + } + return NError(ERRNO_NOERR); + }; + + auto cbCompl = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return NVal::CreateUndefined(env); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::THREE) { + return NAsyncWorkPromise(env, thisVar).Schedule(GRANT_URI_NAME, cbExec, cbCompl).val_; + } else { + NVal cb(env, funcArg[NARG_POS::FOURTH]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule(GRANT_URI_NAME, cbExec, cbCompl).val_; + } + } +} // namespace ModuleFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.h new file mode 100644 index 00000000..d7c654b2 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_share/grant_uri_permission.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRANT_URI_PERMISSION_H +#define GRANT_URI_PERMISSION_H + +#include "filemgmt_libn.h" +#include "iremote_broker.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileShare { + +using namespace std; + +const string MEDIA_GRANT_URI_PERMISSION = + "datashare:///media/bundle_permission_insert_operation/bundle_permission_insert_operation"; +const string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const string MEDIA_FILEMODE_READONLY = "r"; +const string GRANT_URI_NAME = "file_share_grant_uri_permission"; +const string MEDIA_API_VERSION_10 = "?api_version=10"; +const string PERMISSION_BUNDLE_NAME = "bundle_name"; +const string PERMISSION_FILE_ID = "file_id"; +const string PERMISSION_MODE = "mode"; +const string PERMISSION_TABLE_TYPE = "table_type"; +const string MEDIA_FILE_URI_PHOTO_PREFEX = "file://media/Photo/"; +const string MEDIA_FILE_URI_AUDIO_PREFEX = "file://media/Audio/"; +const string MEDIA_FILE_URI_VIDEO_PREFEX = "file://media/video/"; +const string MEDIA_FILE_URI_IMAGE_PREFEX = "file://media/image/"; +const string MEDIA_FILE_URI_FILE_PREFEX = "file://media/file/"; +const string MEDIA_FILE_URI_Audio_PREFEX = "file://media/audio/"; + +class FileShareGrantToken : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.fileshare.grantUriPermission"); + + FileShareGrantToken() = default; + virtual ~FileShareGrantToken() noexcept = default; +}; + +class GrantUriPermission final { +public: + static napi_value Async(napi_env env, napi_callback_info info); +}; +} // namespace ModuleFileShare +} // namespace AppFileService +} // namespace OHOS +#endif // GRANT_URI_PERMISSION_H diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp new file mode 100644 index 00000000..81118b23 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "file_uri_n_exporter.h" +#include "get_uri_from_path.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { +/*********************************************** + * Module export and register + ***********************************************/ +napi_value FileUriExport(napi_env env, napi_value exports) +{ + static napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("getUriFromPath", GetUriFromPath::Sync), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} + +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = FileUriExport, + .nm_modname = "file.fileuri", + .nm_priv = ((void *)0), + .reserved = {0} +}; + +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} +} // namespace ModuleFileUri +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.h new file mode 100644 index 00000000..b37a3d94 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/file_uri_n_exporter.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILE_URI_N_EXPOTER_H +#define FILE_URI_N_EXPOTER_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { + napi_value FileUriExport(napi_env env, napi_value exports); +} // namespace ModuleFileUri +} // namespace AppFileService +} // namespace OHOS +#endif // FILE_URI_N_EXPOTER_H diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.cpp new file mode 100644 index 00000000..da98d861 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "get_uri_from_path.h" + +#include "status_receiver_host.h" + +#include "common_func.h" +#include "log.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { +using namespace OHOS::FileManagement::LibN; + +napi_value GetUriFromPath::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + LOGE("GetUriFromPath::Sync Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!succPath) { + LOGE("GetUriFromPath::Sync get path parameter failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + std::string uri = CommonFunc::GetUriFromPath(path.get()); + if (uri == "") { + LOGE("GetUriFromPath failed!"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + return NVal::CreateUTF8String(env, uri).val_; +} + +} // namespace ModuleFileUri +} // namespace AppFileService +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.h similarity index 50% rename from datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h rename to mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.h index 0c7af901..8adb88fb 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_store_observer_impl.h +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/file_uri/get_uri_from_path.h @@ -13,26 +13,21 @@ * limitations under the License. */ -#ifndef DISTRIBUTED_RDB_STORE_OBSERVER_H -#define DISTRIBUTED_RDB_STORE_OBSERVER_H +#ifndef GET_URI_FROM_PATH_H +#define GET_URI_FROM_PATH_H -#include -#include "store_observer.h" +#include +#include "filemgmt_libn.h" -namespace OHOS::DistributedRdb { -class RdbServiceImpl; -class RdbStoreObserverImpl : public DistributedDB::StoreObserver { +namespace OHOS { +namespace AppFileService { +namespace ModuleFileUri { +class GetUriFromPath final { public: - explicit RdbStoreObserverImpl(RdbServiceImpl* owner, pid_t pid = 0, uint32_t tokenId = 0); - - ~RdbStoreObserverImpl() override; - - void OnChange(const DistributedDB::StoreChangedData &data) override; - -private: - pid_t pid_ = 0; - uint32_t tokenId_ = 0; - RdbServiceImpl* owner_ = nullptr; + static napi_value Sync(napi_env env, napi_callback_info info); }; -} // namespace OHOS::DistributedRdb -#endif +} // namespace ModuleFileUri +} // namespace AppFileService +} // namespace OHOS + +#endif // GET_URI_FROM_PATH_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.cpp new file mode 100644 index 00000000..9569c7a3 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.cpp @@ -0,0 +1,137 @@ +/* + * 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 "remotefileshare_n_exporter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +using namespace FileManagement::LibN; +using namespace std; +namespace { + constexpr int HMDFS_CID_SIZE = 64; + constexpr unsigned HMDFS_IOC = 0xf2; + const std::string SHARE_PATH = "/data/storage/el2/distributedfiles/.share"; +} + +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) + +struct hmdfs_share_control { + int src_fd; + char cid[HMDFS_CID_SIZE]; +}; + +static NError CreateSharePath(const int src_fd, const std::string &cid) +{ + struct hmdfs_share_control sc; + int32_t ret = 0; + int32_t dirFd; + + if (access(SHARE_PATH.c_str(), F_OK) != 0) { + ret = mkdir(SHARE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IXOTH); + if (ret < 0) { + return NError(errno); + } + } + + char realPath[PATH_MAX] = {0}; + if (!realpath(SHARE_PATH.c_str(), realPath)) { + return NError(errno); + } + dirFd = open(realPath, O_RDONLY); + if (dirFd < 0) { + return NError(errno); + } + + sc.src_fd = src_fd; + if (memcpy_s(sc.cid, HMDFS_CID_SIZE, cid.c_str(), cid.size()) != 0) { + close(dirFd); + return NError(ENOMEM); + } + + ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc); + if (ret < 0) { + close(dirFd); + return NError(errno); + } + + close(dirFd); + return NError(ERRNO_NOERR); +} + +napi_value CreateSharePath(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(static_cast(NARG_CNT::TWO), static_cast(NARG_CNT::THREE))) { + NError(EINVAL).ThrowErr(env, "Number of arguments unmatched"); + return nullptr; + } + + bool succ = false; + int src_fd; + std::unique_ptr cid; + size_t cidLen; + tie(succ, src_fd) = NVal(env, funcArg[static_cast(NARG_POS::FIRST)]).ToInt32(); + if (!succ) { + NError(EINVAL).ThrowErr(env, "Invalid fd"); + return nullptr; + } + tie(succ, cid, cidLen) = NVal(env, funcArg[static_cast(NARG_POS::SECOND)]).ToUTF8String(); + if (!succ || cidLen != HMDFS_CID_SIZE) { + NError(EINVAL).ThrowErr(env, "Invalid cid"); + return nullptr; + } + + std::string cidString(cid.get()); + auto cbExec = [src_fd, cidString]() -> NError { + return CreateSharePath(src_fd, cidString); + }; + auto cbComplete = [](napi_env env, NError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return NVal::CreateUTF8String(env, SHARE_PATH); + } + }; + std::string procedureName = "CreateSharePath"; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == static_cast(NARG_CNT::TWO)) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NVal cb(env, funcArg[static_cast(NARG_POS::THIRD)]); + if (cb.TypeIs(napi_function)) { + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; + } else { + NError(EINVAL).ThrowErr(env, "Callback function error"); + return nullptr; + } + } + return NVal::CreateUndefined(env).val_; +} +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.h new file mode 100644 index 00000000..34938bf8 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_n_exporter.h @@ -0,0 +1,28 @@ +/* + * 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 REMOTEFILESHARE_N_EXPORTER_H +#define REMOTEFILESHARE_N_EXPORTER_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +napi_value CreateSharePath(napi_env env, napi_callback_info info); +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS +#endif // REMOTEFILESHARE_N_EXPORTER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.cpp b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.cpp new file mode 100644 index 00000000..69c67208 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.cpp @@ -0,0 +1,37 @@ +/* + * 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 "remotefileshare_napi.h" +#include "remotefileshare_n_exporter.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +/*********************************************** + * Module export and register + ***********************************************/ +napi_value RemoteFileShareExport(napi_env env, napi_value exports) +{ + static napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("createSharePath", CreateSharePath), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} + +NAPI_MODULE(remotefileshare, RemoteFileShareExport) +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.h b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.h new file mode 100644 index 00000000..462f6c49 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/interfaces/kits/js/remote_file_share/remotefileshare_napi.h @@ -0,0 +1,27 @@ +/* + * 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 REMOTEFILESHARE_NAPI_H +#define REMOTEFILESHARE_NAPI_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS +#endif // REMOTEFILESHARE_NAPI_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/BUILD.gn new file mode 100644 index 00000000..9ec3a7ac --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +ohos_executable("backup_tool") { + sources = [ + "src/main.cpp", + "src/tools_op.cpp", + "src/tools_op_backup.cpp", + "src/tools_op_check_sa.cpp", + "src/tools_op_help.cpp", + "src/tools_op_restore.cpp", + "src/tools_op_restore_async.cpp", + ] + + defines = [ + "LOG_DOMAIN=0xD004304", + "LOG_TAG=\"BackupTool\"", + ] + + include_dirs = [ "include" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + ] + + deps = [ + "${path_backup}/interfaces/inner_api/native/backup_kit_inner:backup_kit_inner", + "${path_backup}/utils/:backup_utils", + "${path_jsoncpp}:jsoncpp", + ] + + use_exceptions = true + install_enable = true + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/include/tools_op.h b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/include/tools_op.h new file mode 100644 index 00000000..79b063c1 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/include/tools_op.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_TOOLS_OP_H +#define OHOS_FILEMGMT_BACKUP_TOOLS_OP_H + +#include +#include +#include +#include +#include + +namespace OHOS::FileManagement::Backup { +class ToolsOp { +public: + using CRefVStrView = const std::vector &; + struct CmdInfo { + std::string paramName; + bool repeatable = false; + }; + + struct Descriptor { + // 命令名,必填 + std::vector opName; + // 参数,选填 + std::vector argList; + // 命令帮助语句,选填 + std::function funcGenHelpMsg; + // 命令执行主体,必填 + std::function> &args)> funcExec; + }; + + /** + * @brief 构造一个操作 + * + * @param desc 操作具体信息 + */ + explicit ToolsOp(Descriptor &&desc) : desc_(std::move(desc)) {} + + /** + * @brief 获取当前操作的名称。操作由多条字符串构成时,之间由空格隔开 + * + * @return const std::string 当前操作的名称 + */ + const std::string GetName() const; + + /** + * @brief 获取当前操作的参数 + * + * @return std::vector 当前参数的向量 + */ + const std::vector GetParams() const + { + return desc_.argList; + } + + /** + * @brief 获取当前操作的原始具体信息 + * + * @return const Descriptor& 当前操作的原始具体信息 + */ + const Descriptor &GetDescriptor() const + { + return desc_; + } + + /** + * @brief 获取所有操作 + * + * @return const std::vector& 所有操作 + */ + static const std::vector &GetAllOperations() + { + return ToolsOp::opsAvailable_; + } + + /** + * @brief 注册一个操作 + * + * @param op 操作 + * @return true 注册成功 + * @return false 注册失败 + */ + static bool Register(ToolsOp &&op); + + /** + * @brief 将当前操作与主函数给定的操作相匹配(大小写敏感) + * + * @param op 给定操作 + * @return true 匹配成功 + * @return false 匹配失败 + */ + bool TryMatch(CRefVStrView op) const; + + /** + * @brief 使用主函数给定的参数表执行当前操作 + * + * @param args 给定参数表 + * @return int 错误码(0 表示成功,非零表示失败) + */ + int Execute(std::map> mapArg) const; + +private: + Descriptor desc_; + static inline std::vector opsAvailable_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_TOOLS_OP_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/main.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/main.cpp new file mode 100644 index 00000000..ae8d7113 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/main.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "errors.h" +#include "tools_op.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; + +optional>> GetArgsMap(int argc, char *const argv[], const vector &argList) +{ + int i = 0; + map mapOptToName; + vector vecLongOptions; + for (auto &&arg : argList) { + mapOptToName[i] = arg.paramName; + vecLongOptions.emplace_back(option { + .name = arg.paramName.c_str(), + .has_arg = required_argument, + .flag = nullptr, + .val = i++, + }); + } + vecLongOptions.emplace_back(option {nullptr, 0, nullptr, 0}); + + int opt = 0; + int options_index = 0; + map> mapArgToVals; + while ((opt = getopt_long(argc, argv, "", vecLongOptions.data(), &options_index)) != -1) { + if (opt == '?') { + // "我们匹配到了一个奇怪的命令 返回 nullopt,getopt_long 在opterr 未被赋值0时 会自动打印未被定义参数到终端" + return nullopt; + } + string argName = mapOptToName[opt]; + if (mapArgToVals.find(argName) != mapArgToVals.end() && argList[opt].repeatable == true) { + mapArgToVals[argName].emplace_back(optarg); + } else if (mapArgToVals.find(argName) != mapArgToVals.end()) { + fprintf(stderr, "%s can only be entered once, but you repeat it.\n", argName.c_str()); + return nullopt; + } else { + mapArgToVals.emplace(argName, vector {optarg}); + } + } + return mapArgToVals; +} + +int ParseOpAndExecute(int argc, char *const argv[]) +{ + int flag = -1; + for (int i = 1; i < argc; i++) { + // 暂存 {argv[1]...argv[i]}; + vector curOp; + for (int j = 1; j <= i; ++j) { + curOp.emplace_back(argv[j]); + } + + // 尝试匹配当前命令,成功后执行 + auto tryOpSucceed = [&curOp](const ToolsOp &op) { return op.TryMatch(curOp); }; + auto &&opeartions = ToolsOp::GetAllOperations(); + auto matchedOp = find_if(opeartions.begin(), opeartions.end(), tryOpSucceed); + if (matchedOp != opeartions.end()) { + vector argList = matchedOp->GetParams(); + optional>> mapNameToArgs = GetArgsMap(argc, argv, argList); + if (mapNameToArgs.has_value()) { + flag = matchedOp->Execute(mapNameToArgs.value()); + } + } + } + if (flag != 0) { + printf("backup_tool: missing operand\nTry 'backup_tool help' for more information.\n"); + } + return flag; +} +} // namespace OHOS::FileManagement::Backup + +int main(int argc, char *const argv[]) +{ + return OHOS::FileManagement::Backup::ParseOpAndExecute(argc, argv); +} \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op.cpp new file mode 100644 index 00000000..782de8c2 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tools_op.h" + +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; + +const std::string ToolsOp::GetName() const +{ + std::stringstream ss; + + auto &&allSubOps = desc_.opName; + for (size_t j = 0; j < allSubOps.size(); ++j) { + ss << allSubOps[j]; + if (j != allSubOps.size() - 1) { + ss << ' '; + } + } + + return ss.str(); +} + +bool ToolsOp::Register(ToolsOp &&op) +{ + auto &&opName = op.GetDescriptor().opName; + auto isIncorrect = [&opName](const std::string_view &subOp) { + std::vector patterns { + "\\W", // 匹配任意不是字母、数字、下划线的字符 + "^$", // 匹配空串 + }; + + for (auto subOp : opName) { + for (auto pattern : patterns) { + std::regex re(pattern); + if (std::regex_search(string(subOp), re)) { + fprintf(stderr, "Sub-op '%s' failed to pass regex '%s'\n", subOp.data(), pattern.c_str()); + return true; + } + } + } + + return false; + }; + if (std::any_of(opName.begin(), opName.end(), isIncorrect)) { + fprintf(stderr, "Failed to register an illegal operation '%s'\n", op.GetName().c_str()); + return false; + } + + ToolsOp::opsAvailable_.emplace_back(std::move(op)); + + // sort with ascending order + std::sort(opsAvailable_.begin(), opsAvailable_.end(), [](const ToolsOp &lop, const ToolsOp &rop) { + return lop.desc_.opName < rop.desc_.opName; + }); + return true; +} + +bool ToolsOp::TryMatch(CRefVStrView op) const +{ + return op == desc_.opName; +} + +int ToolsOp::Execute(map> args) const +{ + if (!desc_.funcExec) { + fprintf(stderr, "Incomplete operation: executor is missing\n"); + return -EPERM; + } + return desc_.funcExec(args); +} +} // namespace OHOS::FileManagement::Backup diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_backup.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_backup.cpp new file mode 100644 index 00000000..c5ca37b0 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_backup.cpp @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_file.h" +#include "b_json/b_json_entity_ext_manage.h" +#include "b_resources/b_constants.h" +#include "backup_kit_inner.h" +#include "base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter/hitrace_meter.h" +#include "service_proxy.h" +#include "tools_op.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +class Session { +public: + void UpdateBundleReceivedFiles(const BundleName &bundleName, const string &fileName) + { + lock_guard lk(lock_); + bundleStatusMap_[bundleName].receivedFile.insert(fileName); + TryClearBundleOfMap(bundleName); + } + + void SetIndexFiles(const BundleName &bundleName, UniqueFd fd) + { + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + lock_guard lk(lock_); + bundleStatusMap_[bundleName].indexFile = cache.GetExtManage(); + } + + void TryNotify(bool flag = false) + { + if (flag == true) { + ready_ = true; + cv_.notify_all(); + } else if (bundleStatusMap_.size() == 0 && cnt_ == 0 && isAllBundelsFinished.load()) { + ready_ = true; + cv_.notify_all(); + } + } + + void UpdateBundleFinishedCount() + { + lock_guard lk(lock_); + cnt_--; + } + + void SetBundleFinishedCount(uint32_t cnt) + { + cnt_ = cnt; + } + + void Wait() + { + unique_lock lk(lock_); + cv_.wait(lk, [&] { return ready_; }); + } + + unique_ptr session_ = {}; + +private: + struct BundleStatus { + set receivedFile; + set indexFile; + }; + + void TryClearBundleOfMap(const BundleName &bundleName) + { + if (bundleStatusMap_[bundleName].indexFile == bundleStatusMap_[bundleName].receivedFile) { + bundleStatusMap_.erase(bundleName); + } + } + + map bundleStatusMap_; + mutable condition_variable cv_; + mutex lock_; + bool ready_ = false; + uint32_t cnt_ {0}; + +public: + std::atomic isAllBundelsFinished {false}; +}; + +static string GenHelpMsg() +{ + return "\t\tThis operation helps to backup application data.\n" + "\t\t--isLocal\t\t This parameter should be true or flase; true: local backup false: others.\n" + "\t\t--pathCapFile\t\t This parameter should be the path of the capability file.\n" + "\t\t--bundle\t\t This parameter is bundleName."; +} + +static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, UniqueFd fd) +{ + printf("FileReady owner = %s, fileName = %s, sn = %u, fd = %d\n", fileInfo.owner.c_str(), fileInfo.fileName.c_str(), + fileInfo.sn, fd.Get()); + string tmpPath = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + fileInfo.owner; + if (access(tmpPath.data(), F_OK) != 0 && mkdir(tmpPath.data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + if (!regex_match(fileInfo.fileName, regex("^[0-9a-zA-Z_.]+$"))) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "Filename is not alphanumeric"); + } + UniqueFd fdLocal(open((tmpPath + "/" + fileInfo.fileName).data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU)); + if (fdLocal < 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BFile::SendFile(fdLocal, fd); + if (fileInfo.fileName == BConstants::EXT_BACKUP_MANAGE) { + ctx->SetIndexFiles(fileInfo.owner, move(fd)); + } else { + ctx->UpdateBundleReceivedFiles(fileInfo.owner, fileInfo.fileName); + } + ctx->TryNotify(); +} + +static void OnBundleStarted(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleStarted errCode = %d, BundleName = %s\n", err, name.c_str()); + if (err != 0) { + ctx->isAllBundelsFinished.store(true); + ctx->UpdateBundleFinishedCount(); + ctx->TryNotify(); + } +} + +static void OnBundleFinished(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleFinished errCode = %d, BundleName = %s\n", err, name.c_str()); + ctx->UpdateBundleFinishedCount(); + ctx->TryNotify(); +} + +static void OnAllBundlesFinished(shared_ptr ctx, ErrCode err) +{ + ctx->isAllBundelsFinished.store(true); + if (err == 0) { + printf("backup successful\n"); + } else { + printf("Failed to Unplanned Abort error: %d\n", err); + ctx->TryNotify(true); + return; + } + ctx->TryNotify(); +} + +static void OnBackupServiceDied(shared_ptr ctx) +{ + printf("backupServiceDied\n"); + ctx->TryNotify(true); +} + +static void BackupToolDirSoftlinkToBackupDir() +{ + // 判断BConstants::BACKUP_TOOL_LINK_DIR 是否是软链接 + if (access(BConstants::BACKUP_TOOL_LINK_DIR.data(), F_OK) == 0) { + struct stat inStat = {}; + if (lstat(BConstants::BACKUP_TOOL_LINK_DIR.data(), &inStat) == -1) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + + if ((inStat.st_mode & S_IFMT) == S_IFLNK) { + return; + } + // 非软连接删除重新创建 + if (!ForceRemoveDirectory(BConstants::BACKUP_TOOL_LINK_DIR.data())) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + } + + if (access(BConstants::GetSaBundleBackupToolDir(BConstants::DEFAULT_USER_ID).data(), F_OK) != 0 && + mkdir(BConstants::GetSaBundleBackupToolDir(BConstants::DEFAULT_USER_ID).data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + if (symlink(BConstants::GetSaBundleBackupToolDir(BConstants::DEFAULT_USER_ID).data(), + BConstants::BACKUP_TOOL_LINK_DIR.data()) == -1) { + HILOGE("failed to create soft link file %{public}s errno : %{public}d", + BConstants::BACKUP_TOOL_LINK_DIR.data(), errno); + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } +} + +static int32_t InitPathCapFile(const string &pathCapFile, vector bundleNames) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "InitPathCapFile"); + // SELinux backup_tool工具/data/文件夹下创建文件夹 SA服务因root用户的自定义标签无写入权限 此处调整为软链接形式 + BackupToolDirSoftlinkToBackupDir(); + + if (access((BConstants::BACKUP_TOOL_RECEIVE_DIR).data(), F_OK) != 0 && + mkdir((BConstants::BACKUP_TOOL_RECEIVE_DIR).data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + + UniqueFd fdLocal(open(pathCapFile.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)); + if (fdLocal < 0) { + fprintf(stderr, "Failed to open file. error: %d %s\n", errno, strerror(errno)); + return -EPERM; + } + auto proxy = ServiceProxy::GetInstance(); + if (!proxy) { + fprintf(stderr, "Get an empty backup sa proxy\n"); + return -EPERM; + } + BFile::SendFile(fdLocal, proxy->GetLocalCapabilities()); + + auto ctx = make_shared(); + ctx->session_ = BSessionBackup::Init( + BSessionBackup::Callbacks {.onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2), + .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(OnBundleFinished, ctx, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(OnAllBundlesFinished, ctx, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, ctx)}); + if (ctx->session_ == nullptr) { + printf("Failed to init backup\n"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -EPERM; + } + int ret = ctx->session_->AppendBundles(bundleNames); + if (ret != 0) { + printf("backup append bundles error: %d\n", ret); + throw BError(BError::Codes::TOOL_INVAL_ARG, "backup append bundles error"); + } + + ctx->SetBundleFinishedCount(bundleNames.size()); + ctx->Wait(); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return 0; +} + +static int Exec(map> &mapArgToVal) +{ + if (mapArgToVal.find("pathCapFile") == mapArgToVal.end() || mapArgToVal.find("bundles") == mapArgToVal.end() || + mapArgToVal.find("isLocal") == mapArgToVal.end()) { + return -EPERM; + } + return InitPathCapFile(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"]); +} + +/** + * @brief The hack behind is that "variable with static storage duration has initialization or a destructor with side + * effects; it shall not be eliminated even if it appears to be unused" -- point 2.[basic.stc.static].c++ draft + * + */ +static bool g_autoRegHack = ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"backup"}, + .argList = {{ + .paramName = "pathCapFile", + .repeatable = false, + }, + { + .paramName = "bundles", + .repeatable = true, + }, + { + .paramName = "isLocal", + .repeatable = false, + }}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, +}}); +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_check_sa.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_check_sa.cpp new file mode 100644 index 00000000..daabbb63 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_check_sa.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "errors.h" +#include "service_proxy.h" +#include "tools_op.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +static string GenHelpMsg() +{ + return "\tThis operation helps to check if the backup sa is available."; +} + +static int Exec(map> &mapArgToVal) +{ + auto proxy = ServiceProxy::GetInstance(); + if (!proxy) { + fprintf(stderr, "Get an empty backup sa proxy\n"); + return -EFAULT; + } + + printf("successful\n"); + return 0; +} + +/** + * @brief The hack behind is that "variable with static storage duration has initialization or a destructor with side + * effects; it shall not be eliminated even if it appears to be unused" -- point 2.[basic.stc.static].c++ draft + * + */ +static bool g_autoRegHack = ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"check", "sa"}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, +}}); +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_help.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_help.cpp new file mode 100644 index 00000000..df60b209 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_help.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "tools_op.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +static string GenHelpMsg() +{ + return "\t\tThis operation helps to dump the help messages."; +} + +static int Exec(map> &mapArgToVal) +{ + stringstream ss; + auto &&allOps = ToolsOp::GetAllOperations(); + ss << "Usage: backup_tool [OPTION]... [ARG]..." << endl; + for (size_t i = 0; i < allOps.size(); ++i) { + auto desc = allOps[i].GetDescriptor(); + + // echo: \n + ss << allOps[i].GetName(); + + // echo: help msgs\n\n + if (desc.funcGenHelpMsg) { + ss << desc.funcGenHelpMsg() << endl; + } + if (i != allOps.size() - 1) { + ss << endl; + } + } + printf("%s", ss.str().c_str()); + return 0; +} + +/** + * @brief The hack behind is that "variable with static storage duration has initialization or a destructor with side + * effects; it shall not be eliminated even if it appears to be unused" -- point 2.[basic.stc.static].c++ draft + * + */ +static bool g_autoRegHack = ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"help"}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, +}}); +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore.cpp new file mode 100644 index 00000000..c5259997 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore.cpp @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_dir.h" +#include "b_filesystem/b_file.h" +#include "b_json/b_json_entity_caps.h" +#include "b_json/b_json_entity_ext_manage.h" +#include "b_resources/b_constants.h" +#include "backup_kit_inner.h" +#include "base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter/hitrace_meter.h" +#include "errors.h" +#include "service_proxy.h" +#include "tools_op.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +class Session { +public: + void UpdateBundleSendFiles(const BundleName &bundleName, const string &fileName) + { + lock_guard lk(lock_); + bundleStatusMap_[bundleName].sendFile.insert(fileName); + } + + void UpdateBundleSentFiles(const BundleName &bundleName, const string &fileName) + { + lock_guard lk(lock_); + bundleStatusMap_[bundleName].sentFile.insert(fileName); + TryClearBundleOfMap(bundleName); + } + + void ClearBundleOfMap(const BundleName &bundleName) + { + lock_guard lk(lock_); + bundleStatusMap_.erase(bundleName); + } + + void TryNotify(bool flag = false) + { + if (flag == true) { + ready_ = true; + cv_.notify_all(); + } else if (bundleStatusMap_.size() == 0 && cnt_ == 0 && isAllBundelsFinished.load()) { + ready_ = true; + cv_.notify_all(); + } + } + + void UpdateBundleFinishedCount() + { + lock_guard lk(lock_); + cnt_--; + } + + void SetBundleFinishedCount(uint32_t cnt) + { + cnt_ = cnt; + } + + void Wait() + { + unique_lock lk(lock_); + cv_.wait(lk, [&] { return ready_; }); + } + + unique_ptr session_ = {}; + +private: + struct BundleStatus { + set sendFile; + set sentFile; + }; + + void TryClearBundleOfMap(const BundleName &bundleName) + { + if (bundleStatusMap_[bundleName].sendFile == bundleStatusMap_[bundleName].sentFile) { + bundleStatusMap_.erase(bundleName); + } + } + + map bundleStatusMap_; + mutable condition_variable cv_; + mutex lock_; + bool ready_ = false; + uint32_t cnt_ {0}; + +public: + std::atomic isAllBundelsFinished {false}; +}; + +static string GenHelpMsg() +{ + return "\t\tThis operation helps to restore application data.\n" + "\t\t--pathCapFile\t\t This parameter should be the path of the capability file.\n" + "\t\t--bundle\t\t This parameter is bundleName."; +} + +static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, UniqueFd fd) +{ + printf("FileReady owner = %s, fileName = %s, sn = %u, fd = %d\n", fileInfo.owner.c_str(), fileInfo.fileName.c_str(), + fileInfo.sn, fd.Get()); + if (!regex_match(fileInfo.fileName, regex("^[0-9a-zA-Z_.]+$")) && + fileInfo.fileName != BConstants::RESTORE_INSTALL_PATH) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "Filename is not alphanumeric"); + } + string tmpPath; + if (fileInfo.fileName == BConstants::RESTORE_INSTALL_PATH) { + printf("OnFileReady bundle hap\n"); + tmpPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + fileInfo.owner + ".hap"; + } else { + tmpPath = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + fileInfo.owner + "/" + fileInfo.fileName; + } + if (access(tmpPath.data(), F_OK) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + UniqueFd fdLocal(open(tmpPath.data(), O_RDONLY)); + if (fdLocal < 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BFile::SendFile(fd, fdLocal); + int ret = ctx->session_->PublishFile(fileInfo); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } + if (fileInfo.fileName != BConstants::RESTORE_INSTALL_PATH) { + ctx->UpdateBundleSentFiles(fileInfo.owner, fileInfo.fileName); + } + ctx->TryNotify(); +} + +static void OnBundleStarted(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleStarted errCode = %d, BundleName = %s\n", err, name.c_str()); + if (err != 0) { + ctx->UpdateBundleFinishedCount(); + ctx->isAllBundelsFinished.store(true); + ctx->ClearBundleOfMap(name); + ctx->TryNotify(); + } +} + +static void OnBundleFinished(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleFinished errCode = %d, BundleName = %s\n", err, name.c_str()); + ctx->UpdateBundleFinishedCount(); + if (err != 0) { + ctx->isAllBundelsFinished.store(true); + ctx->ClearBundleOfMap(name); + } + ctx->TryNotify(); +} + +static void OnAllBundlesFinished(shared_ptr ctx, ErrCode err) +{ + ctx->isAllBundelsFinished.store(true); + if (err == 0) { + printf("Restore successful\n"); + } else { + printf("Failed to Unplanned Abort error: %d\n", err); + ctx->TryNotify(true); + return; + } + ctx->TryNotify(); +} + +static void OnBackupServiceDied(shared_ptr ctx) +{ + printf("backupServiceDied\n"); + ctx->TryNotify(true); +} + +static void RestoreApp(shared_ptr restore, vector &bundleNames) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "RestoreApp"); + if (!restore || !restore->session_) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + for (auto &bundleName : bundleNames) { + if (!regex_match(bundleName, regex("^[0-9a-zA-Z_.]+$"))) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "bundleName is not alphanumeric"); + } + string path = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + bundleName; + if (access(path.data(), F_OK) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + const auto [err, filePaths] = BDir::GetDirFiles(path); + if (err != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "error path"); + } + // install bundle.hap + string installPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + bundleName + ".hap"; + if (access(installPath.data(), F_OK) == 0) { + printf("install bundle hap %s\n", installPath.c_str()); + restore->session_->GetFileHandle(bundleName, string(BConstants::RESTORE_INSTALL_PATH)); + } + for (auto &filePath : filePaths) { + string fileName = filePath.substr(filePath.rfind("/") + 1); + restore->session_->GetFileHandle(bundleName, fileName); + restore->UpdateBundleSendFiles(bundleName, fileName); + } + } + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); +} + +static bool GetRealPath(string &path) +{ + unique_ptr absPath = make_unique(PATH_MAX + 1); + if (realpath(path.c_str(), absPath.get()) == nullptr) { + return false; + } + + path = absPath.get(); + if (access(path.data(), F_OK) != 0) { + return false; + } + + return true; +} + +static int32_t InitPathCapFile(const string &pathCapFile, vector bundleNames) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); + string realPath = pathCapFile; + if (!GetRealPath(realPath)) { + fprintf(stderr, "path to realpath error"); + return -errno; + } + + UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU)); + if (fd < 0) { + fprintf(stderr, "Failed to open file error: %d %s\n", errno, strerror(errno)); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -errno; + } + if (access(BConstants::BACKUP_TOOL_INSTALL_DIR.data(), F_OK) == 0) { + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + vector bundleInfos; + for (auto name : bundleNames) { + string installPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + name + ".hap"; + if (access(installPath.data(), F_OK) == 0) { + bool needToInstall = true; + bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {.name = name, .needToInstall = needToInstall}); + } + } + cache.SetBundleInfos(bundleInfos); + cachedEntity.Persist(); + fd = move(cachedEntity.GetFd()); + } + auto ctx = make_shared(); + ctx->session_ = BSessionRestore::Init( + BSessionRestore::Callbacks {.onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2), + .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(OnBundleFinished, ctx, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(OnAllBundlesFinished, ctx, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, ctx)}); + if (ctx->session_ == nullptr) { + printf("Failed to init restore\n"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -EPERM; + } + int ret = ctx->session_->AppendBundles(move(fd), bundleNames); + if (ret != 0) { + printf("restore append bundles error: %d\n", ret); + return -ret; + } + ctx->SetBundleFinishedCount(bundleNames.size()); + RestoreApp(ctx, bundleNames); + ctx->Wait(); + return 0; +} + +static int Exec(map> &mapArgToVal) +{ + if (mapArgToVal.find("pathCapFile") == mapArgToVal.end() || mapArgToVal.find("bundles") == mapArgToVal.end()) { + return -EPERM; + } + return InitPathCapFile(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"]); +} + +/** + * @brief The hack behind is that "variable with static storage duration has initialization or a destructor with side + * effects; it shall not be eliminated even if it appears to be unused" -- point 2.[basic.stc.static].c++ draft + * + */ +static bool g_autoRegHack = ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"restore"}, + .argList = {{ + .paramName = "pathCapFile", + .repeatable = false, + }, + { + .paramName = "bundles", + .repeatable = true, + }}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, +}}); +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore_async.cpp b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore_async.cpp new file mode 100644 index 00000000..104d2194 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/tools/backup_tool/src/tools_op_restore_async.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "b_filesystem/b_dir.h" +#include "b_filesystem/b_file.h" +#include "b_json/b_json_entity_caps.h" +#include "b_json/b_json_entity_ext_manage.h" +#include "b_resources/b_constants.h" +#include "backup_kit_inner.h" +#include "errors.h" +#include "hitrace_meter.h" +#include "service_proxy.h" +#include "tools_op.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +class SessionAsync { +public: + void TryNotify(bool flag = false) + { + if (flag == true) { + ready_ = true; + cv_.notify_all(); + } + } + + void Wait() + { + unique_lock lk(lock_); + cv_.wait(lk, [&] { return ready_; }); + } + + shared_ptr session_ = {}; + +private: + mutable condition_variable cv_; + mutex lock_; + bool ready_ = false; +}; + +static string GenHelpMsg() +{ + return "\tThis operation helps to restore application data.\n" + "\t\t--pathCapFile\t\t This parameter should be the path of the capability file.\n" + "\t\t--bundle\t\t This parameter is bundleName.\n" + "\t\t--userId\t\t This parameter is userId.\n" + "\t\t--restoreType\t\t The parameter is a bool variable. true Simulates the upgrade service scenario; false " + "simulates the application recovery scenario.\n"; +} + +static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, UniqueFd fd) +{ + printf("FileReady owner = %s, fileName = %s, sn = %u, fd = %d\n", fileInfo.owner.c_str(), fileInfo.fileName.c_str(), + fileInfo.sn, fd.Get()); + if (!regex_match(fileInfo.fileName, regex("^[0-9a-zA-Z_.]+$")) && + fileInfo.fileName != BConstants::RESTORE_INSTALL_PATH) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "Filename is not alphanumeric"); + } + string tmpPath; + if (fileInfo.fileName == BConstants::RESTORE_INSTALL_PATH) { + printf("OnFileReady bundle hap\n"); + tmpPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + fileInfo.owner + ".hap"; + } else { + tmpPath = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + fileInfo.owner + "/" + fileInfo.fileName; + } + if (access(tmpPath.data(), F_OK) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BExcepUltils::VerifyPath(tmpPath, false); + UniqueFd fdLocal(open(tmpPath.data(), O_RDONLY)); + if (fdLocal < 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BFile::SendFile(fd, fdLocal); + int ret = ctx->session_->PublishFile(fileInfo); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } +} + +static void OnBundleStarted(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleStarted errCode = %d, BundleName = %s\n", err, name.c_str()); + if (err != 0) { + ctx->TryNotify(true); + } +} + +static void OnBundleFinished(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleFinished errCode = %d, BundleName = %s\n", err, name.c_str()); + if (err != 0) { + ctx->TryNotify(true); + } +} + +static void OnAllBundlesFinished(shared_ptr ctx, ErrCode err) +{ + printf("AllBundlesFinished errCode = %d\n", err); + if (err != 0) { + ctx->TryNotify(true); + } +} + +static void OnBackupServiceDied(shared_ptr ctx) +{ + printf("backupServiceDied\n"); + ctx->TryNotify(true); +} + +static void RestoreApp(shared_ptr restore, vector &bundleNames) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "RestoreApp"); + if (!restore || !restore->session_) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + for (auto &bundleName : bundleNames) { + if (!regex_match(bundleName, regex("^[0-9a-zA-Z_.]+$"))) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "bundleName is not alphanumeric"); + } + string path = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + bundleName; + if (access(path.data(), F_OK) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + const auto [err, filePaths] = BDir::GetDirFiles(path); + if (err != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "error path"); + } + // install bundle.hap + string installPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + bundleName + ".hap"; + if (access(installPath.data(), F_OK) == 0) { + printf("install bundle hap %s\n", installPath.c_str()); + restore->session_->GetFileHandle(bundleName, string(BConstants::RESTORE_INSTALL_PATH)); + } + for (auto &filePath : filePaths) { + string fileName = filePath.substr(filePath.rfind("/") + 1); + restore->session_->GetFileHandle(bundleName, fileName); + } + } + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); +} + +static int32_t ChangeBundleInfo(const string &pathCapFile, const vector &bundleNames, const string &type) +{ + BExcepUltils::VerifyPath(pathCapFile, false); + UniqueFd fd(open(pathCapFile.data(), O_RDWR, S_IRWXU)); + if (fd < 0) { + fprintf(stderr, "Failed to open file error: %d %s\n", errno, strerror(errno)); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -errno; + } + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + vector infos = cache.GetBundleInfos(); + vector bundleInfos; + for (auto name : bundleNames) { + string versionName = string(BConstants::DEFAULT_VERSION_NAME); + uint32_t versionCode = static_cast(BConstants::DEFAULT_VERSION_CODE); + if (type == "false") { + auto iter = find_if(infos.begin(), infos.end(), [name](const auto &it) { return it.name == name; }); + if (iter != infos.end()) { + versionName = iter->versionName; + versionCode = iter->versionCode; + } + } + string installPath = string(BConstants::BACKUP_TOOL_INSTALL_DIR) + name + ".hap"; + bool needToInstall = false; + if (access(installPath.data(), F_OK) == 0) { + needToInstall = true; + } + bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo { + .name = name, .needToInstall = needToInstall, .versionCode = versionCode, .versionName = versionName}); + } + cache.SetBundleInfos(bundleInfos); + cachedEntity.Persist(); + + return 0; +} + +static int32_t AppendBundles(shared_ptr restore, + const string &pathCapFile, + vector bundleNames, + const string &type, + const string &userId) +{ + BExcepUltils::VerifyPath(pathCapFile, false); + UniqueFd fd(open(pathCapFile.data(), O_RDWR, S_IRWXU)); + if (fd < 0) { + fprintf(stderr, "Failed to open file error: %d %s\n", errno, strerror(errno)); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -errno; + } + RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND; + if (type == "true") { + restoreType = RestoreTypeEnum::RESTORE_DATA_READDY; + } + try { + int ret = restore->session_->AppendBundles(move(fd), bundleNames, restoreType, atoi(userId.data())); + if (ret != 0) { + printf("restore append bundles error: %d\n", ret); + return -ret; + } + if (type == "false") { + RestoreApp(restore, bundleNames); + } + } catch (const BError &e) { + printf("restore append bundles error: %d\n", e.GetCode()); + return -1; + } catch (...) { + printf("Unexpected exception"); + return -1; + } + restore->Wait(); + return 0; +} + +static int32_t InitArg(const string &pathCapFile, + const vector &bundleNames, + const string &type, + const string &userId) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); + BExcepUltils::VerifyPath(pathCapFile, false); + + if (ChangeBundleInfo(pathCapFile, bundleNames, type)) { + fprintf(stderr, "ChangeBundleInfo error"); + return -errno; + } + + auto ctx = make_shared(); + ctx->session_ = BSessionRestoreAsync::Init(BSessionRestoreAsync::Callbacks { + .onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2), + .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(OnBundleFinished, ctx, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(OnAllBundlesFinished, ctx, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, ctx)}); + if (ctx->session_ == nullptr) { + printf("Failed to init restore\n"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -EPERM; + } + + return AppendBundles(ctx, pathCapFile, bundleNames, type, userId); +} + +static int Exec(map> &mapArgToVal) +{ + if (mapArgToVal.find("pathCapFile") == mapArgToVal.end() || mapArgToVal.find("bundles") == mapArgToVal.end() || + mapArgToVal.find("restoreType") == mapArgToVal.end() || mapArgToVal.find("userId") == mapArgToVal.end()) { + return -EPERM; + } + return InitArg(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], *(mapArgToVal["restoreType"].begin()), + *(mapArgToVal["userId"].begin())); +} + +/** + * @brief The hack behind is that "variable with static storage duration has initialization or a destructor with side + * effects; it shall not be eliminated even if it appears to be unused" -- point 2.[basic.stc.static].c++ draft + * + */ +static bool g_autoRegHack = ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"restoreAsync"}, + .argList = {{ + .paramName = "pathCapFile", + .repeatable = false, + }, + { + .paramName = "bundles", + .repeatable = true, + }, + { + .paramName = "restoreType", + .repeatable = true, + }, + { + .paramName = "userId", + .repeatable = true, + }}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, +}}); +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/BUILD.gn b/mock/innerkits/filemanagement/app_file_service/utils/BUILD.gn new file mode 100644 index 00000000..3a8524ca --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/BUILD.gn @@ -0,0 +1,105 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/filemanagement/app_file_service/backup.gni") + +config("utils_private_config") { + defines = [ + "LOG_DOMAIN=0xD004305", + "LOG_TAG=\"BackupUtils\"", + ] +} + +config("utils_public_config") { + include_dirs = [ + "include", + "include/b_hilog", + "${path_base}/include", + ] +} + +rust_cxx("backup_cxx_gen") { + sources = [ "rust/src/lib.rs" ] +} + +ohos_rust_static_ffi("backup_cxx_rust") { + sources = [ "rust/src/lib.rs" ] + deps = [ "//third_party/rust/crates/cxx:lib" ] + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_static_library("backup_cxx_cppdeps") { + part_name = "app_file_service" + subsystem_name = "filemanagement" + defines = [ "RUST_CXX_NO_EXCEPTIONS" ] + sources = [ + "//third_party/rust/crates/cxx/include/cxx.h", + "//third_party/rust/crates/cxx/src/cxx.cc", + ] + deps = [ "//third_party/rust/crates/cxx:lib" ] + if (is_win) { + defines += [ "CXX_RS_EXPORT=__declspec(dllexport)" ] + } else { + defines += [ "CXX_RS_EXPORT=__attribute__((visibility(\"default\")))" ] + } +} + +ohos_shared_library("backup_utils") { + sources = [ + "src/b_encryption/b_encryption.cpp", + "src/b_error/b_error.cpp", + "src/b_error/b_excep_utils.cpp", + "src/b_filesystem/b_dir.cpp", + "src/b_filesystem/b_file.cpp", + "src/b_json/b_json_entity_ext_manage.cpp", + "src/b_json/b_json_entity_extension_config.cpp", + "src/b_ohos/startup/backup_para.cpp", + "src/b_process/b_guard_cwd.cpp", + "src/b_process/b_guard_signal.cpp", + "src/b_process/b_process.cpp", + "src/b_tarball/b_tarball_cmdline.cpp", + "src/b_tarball/b_tarball_factory.cpp", + ] + sources += get_target_outputs(":backup_cxx_gen") + + configs = [ ":utils_private_config" ] + public_configs = [ ":utils_public_config" ] + + external_deps = [ + "c_utils:utils", + "faultloggerd:libdfx_dumpcatcher", + "hilog:libhilog", + "init:libbegetutil", + ] + + include_dirs = [ + "${path_init}/interfaces/innerkits/include/syspara", + "${path_backup}/interfaces/inner_api/native/backup_kit_inner/impl", + "${path_rust}/crates/cxx/include", + "${target_gen_dir}/rust/src", + ] + + deps = [ + ":backup_cxx_cppdeps", + ":backup_cxx_gen", + ":backup_cxx_rust", + "${path_jsoncpp}:jsoncpp", + ] + + use_exceptions = true + innerapi_tags = [ "platformsdk" ] + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_encryption/b_encryption.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_encryption/b_encryption.h new file mode 100644 index 00000000..cbd52e06 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_encryption/b_encryption.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_ENCRYPTION_H +#define OHOS_FILEMGMT_BACKUP_B_ENCRYPTION_H + +namespace OHOS::FileManagement::Backup::BEncryption { +unsigned int CalculateChksum(const char *byteBlock, int blockSize); +} // namespace OHOS::FileManagement::Backup::BEncryption + +#endif // OHOS_FILEMGMT_BACKUP_B_ENCRYPTION_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_error.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_error.h new file mode 100644 index 00000000..6c549639 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_error.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 本部件处理错误的原则: + * 原则1:使用异常表示错误,但只有无法处理的问题才算得上是错误,否则只是普通的边界分支; + * 原则2:仅在模块内部使用异常,而在界面层Catch所有异常,从而防止异常扩散; + * 原则3:在注释里通过throw关键字注明可能抛出的异常,通报使用风险。 + */ +#ifndef OHOS_FILEMGMT_BACKUP_B_ERROR_H +#define OHOS_FILEMGMT_BACKUP_B_ERROR_H + +#include +#include +#include +#include +#include +#include +#include + +#if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE) && __has_builtin(__builtin_FUNCTION) +#define DEFINE_SOURCE_LOCATION \ + int lineNo = __builtin_LINE(), const char *fileName = __builtin_FILE(), \ + const char *functionName = __builtin_FUNCTION() +#else +#define DEFINE_SOURCE_LOCATION int lineNo = -1, const char *fileName = "NA", const char *functionName = "NA" +#endif + +namespace OHOS::FileManagement::Backup { +using ErrCode = int; + +class BError : public std::exception { +public: + /** + * @brief 错误码,新增错误码时需要同步补充默认错误信息 + * + */ + enum class Codes : ErrCode { + // 0 无错误 + OK = 0x0, + + // 1~999 标准平台错误 + + // 0x1000~0x1999 backup_utils错误 + UTILS_INVAL_JSON_ENTITY = 0x1000, + UTILS_INVAL_FILE_HANDLE = 0x1001, + UTILS_INVAL_TARBALL_ARG = 0x1002, + UTILS_INVAL_PROCESS_ARG = 0x1003, + UTILS_INTERRUPTED_PROCESS = 0x1004, + + // 0x2000~0x2999 backup_tool错误 + TOOL_INVAL_ARG = 0x2000, + + // 0x3000~0x3999 backup_sa错误 + SA_INVAL_ARG = 0x3000, + SA_BROKEN_IPC = 0x3001, + SA_REFUSED_ACT = 0x3002, + SA_BROKEN_ROOT_DIR = 0x3003, + + // 0x4000~0x4999 backup_SDK错误 + SDK_INVAL_ARG = 0x4000, + SDK_BROKEN_IPC = 0x4001, + SDK_MIXED_SCENARIO = 0x4002, + + // 0x5000~0x5999 backup_ext错误 + EXT_INVAL_ARG = 0x5000, + EXT_BROKEN_FRAMEWORK = 0x5001, + EXT_BROKEN_BACKUP_SA = 0x5002, + EXT_BROKEN_IPC = 0x5003, + }; + + enum BackupErrorCode { + E_IPCSS = 13600001, + E_PERM = 13900001, + E_IO = 13900005, + E_NOMEM = 13900011, + E_INVAL = 13900020, + E_NOSPC = 13900025, + E_UKERR = 13900042, + }; + +public: + /** + * @brief 返回OHOS标准错误码 + * + * @return int 标注错误码 + */ + int GetCode() const; + + /** + * @brief 返回原始错误码 + * + * @return Codes 原始错误码 + */ + Codes GetRawCode() const + { + return code_; + } + + /** + * @brief 返回错误信息 + * + * @return const char* 错误信息 + */ + const char *what() const noexcept override + { + return msg_.c_str(); + } + +public: + /** + * @brief 重载bool操作符,判断当前错误是否是错误 + * + * @return true 是错误 + * @return false 不是错误 + */ + explicit operator bool() const + { + return code_ != Codes::OK; + } + + /** + * @brief 返回OHOS标准错误码 + * + * @return int 标准错误码 + */ + operator int() const + { + return GetCode(); + } + +public: + /** + * @brief 构造错误对象 + * + * @param code 备份系统标准错误码,取自本类中的Codes + * @param lineNo 构造错误对象的行号(不要自己填写) + * @param fileName 构造错误对象的文件(不要自己填写) + * @param functionName 构造错误对象的函数(不要自己填写) + */ + explicit BError(Codes code = Codes::OK, DEFINE_SOURCE_LOCATION) : code_(code) + { + msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_)}); + } + + /** + * @brief 构造错误对象 + * + * @param code 备份系统标准错误码,取自本类中的Codes + * @param extraMsg 追加的详细错误信息 + * @param lineNo 构造错误对象的行号(不要自己填写) + * @param fileName 构造错误对象的文件(不要自己填写) + * @param functionName 构造错误对象的函数(不要自己填写) + */ + BError(Codes code, const std::string_view &extraMsg, DEFINE_SOURCE_LOCATION) : code_(code) + { + msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {mpErrToMsg_.at(code_), extraMsg}); + } + + /** + * @brief 构造错误对象 + * + * @param stdErrno 失败的LIBC调用通过errno返回的错误码 + * @param lineNo 构造错误对象的行号(不要自己填写) + * @param fileName 构造错误对象的文件(不要自己填写) + * @param functionName 构造错误对象的函数(不要自己填写) + */ + explicit BError(int stdErrno, DEFINE_SOURCE_LOCATION) : code_ {stdErrno} + { + std::string rawMsg = std::generic_category().message(stdErrno); + msg_ = WrapMessageWithExtraInfos(fileName, lineNo, functionName, code_, {rawMsg}); + } + +private: + static inline const std::map mpErrToMsg_ = { + {Codes::OK, "No error"}, + {Codes::UTILS_INVAL_JSON_ENTITY, "Json utils operated on an invalid file"}, + {Codes::UTILS_INVAL_FILE_HANDLE, "File utils received an invalid file handle"}, + {Codes::UTILS_INVAL_TARBALL_ARG, "Tarball utils received an invalid argument"}, + {Codes::UTILS_INVAL_PROCESS_ARG, "Process utils received an invalid argument"}, + {Codes::UTILS_INTERRUPTED_PROCESS, "Can't launch a process or the process was corrupted"}, + {Codes::TOOL_INVAL_ARG, "TOOL received invalid arguments"}, + {Codes::SA_INVAL_ARG, "SA received invalid arguments"}, + {Codes::SA_BROKEN_IPC, "SA failed to issue a IPC"}, + {Codes::SA_REFUSED_ACT, "SA refuse to act"}, + {Codes::SA_BROKEN_ROOT_DIR, "SA failed to operate on the given root dir"}, + {Codes::SDK_INVAL_ARG, "SDK received invalid arguments"}, + {Codes::SDK_BROKEN_IPC, "SDK failed to do IPC"}, + {Codes::SDK_MIXED_SCENARIO, "SDK involed backup/restore when doing the contrary"}, + {Codes::EXT_INVAL_ARG, "Extension received an invalid argument"}, + {Codes::EXT_BROKEN_FRAMEWORK, "Extension found the appex framework is broken"}, + {Codes::EXT_BROKEN_BACKUP_SA, "Extension found the backup SA died"}, + {Codes::EXT_BROKEN_IPC, "Extension failed to do IPC"}, + }; + + static inline const std::map errCodeTable_ { + {static_cast(Codes::OK), static_cast(Codes::OK)}, + {static_cast(Codes::UTILS_INVAL_JSON_ENTITY), BackupErrorCode::E_INVAL}, + {static_cast(Codes::UTILS_INVAL_FILE_HANDLE), BackupErrorCode::E_INVAL}, + {static_cast(Codes::UTILS_INVAL_TARBALL_ARG), BackupErrorCode::E_UKERR}, + {static_cast(Codes::UTILS_INVAL_PROCESS_ARG), BackupErrorCode::E_UKERR}, + {static_cast(Codes::UTILS_INTERRUPTED_PROCESS), BackupErrorCode::E_UKERR}, + {static_cast(Codes::TOOL_INVAL_ARG), BackupErrorCode::E_UKERR}, + {static_cast(Codes::SA_INVAL_ARG), BackupErrorCode::E_INVAL}, + {static_cast(Codes::SA_BROKEN_IPC), BackupErrorCode::E_IPCSS}, + {static_cast(Codes::SA_REFUSED_ACT), BackupErrorCode::E_PERM}, + {static_cast(Codes::SA_BROKEN_ROOT_DIR), BackupErrorCode::E_UKERR}, + {static_cast(Codes::SDK_INVAL_ARG), BackupErrorCode::E_INVAL}, + {static_cast(Codes::SDK_BROKEN_IPC), BackupErrorCode::E_IPCSS}, + {static_cast(Codes::SDK_MIXED_SCENARIO), BackupErrorCode::E_INVAL}, + {static_cast(Codes::EXT_INVAL_ARG), BackupErrorCode::E_INVAL}, + {static_cast(Codes::EXT_BROKEN_FRAMEWORK), BackupErrorCode::E_UKERR}, + {static_cast(Codes::EXT_BROKEN_BACKUP_SA), BackupErrorCode::E_IPCSS}, + {static_cast(Codes::EXT_BROKEN_IPC), BackupErrorCode::E_IPCSS}, + {BackupErrorCode::E_IPCSS, BackupErrorCode::E_IPCSS}, + {BackupErrorCode::E_INVAL, BackupErrorCode::E_INVAL}, + {BackupErrorCode::E_UKERR, BackupErrorCode::E_UKERR}, + {BackupErrorCode::E_PERM, BackupErrorCode::E_PERM}, + {BackupErrorCode::E_NOMEM, BackupErrorCode::E_NOMEM}, + {BackupErrorCode::E_NOSPC, BackupErrorCode::E_NOSPC}, + {BackupErrorCode::E_IO, BackupErrorCode::E_IO}, + }; + +private: + Codes code_ {Codes::OK}; + std::string msg_; + +private: + /** + * @brief 生成如下格式的打印信息 → [文件名:行号->函数名] 默认错误信息. 补充错误信息 + * + * @param fileName 构造错误对象的文件 + * @param lineNo 构造错误对象的行号 + * @param functionName 构造错误对象的函数 + * @param msgs 所有待追加的错误信息 + * @return std::string 打印信息 + */ + std::string WrapMessageWithExtraInfos(const char *fileName, + int lineNo, + const char *functionName, + Codes code, + const std::vector &msgs) const; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_ERROR_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_excep_utils.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_excep_utils.h new file mode 100644 index 00000000..25275d60 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_error/b_excep_utils.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H +#define OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H + +#include + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +class BExcepUltils { +public: + /** + * @brief 异常捕获 + * + * @param callBack 回调 + * @return ErrCode 错误码 + */ + static ErrCode ExceptionCatcherLocked(std::function callBack) + { + try { + return callBack(); + } catch (const BError &e) { + return e.GetCode(); + } catch (const std::exception &e) { + HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGE("Unexpected exception"); + return EPERM; + } + } + + /** + * @brief 检查 AbilityInfo 是否有效 + * + * @param AbilityInfo + * @param code 错误码 + * @param msg 错误信息 + * @return 无 + */ + template + static void BAssert(const T &t, const BError::Codes &code, const std::string_view msg = "") + { + if (!t) { + if (msg.empty()) { + throw BError(code); + } else { + throw BError(code, msg); + } + } + } + + /** + * @brief 校验路径 + * + * @param path + * @param isExtension + */ + static void VerifyPath(const std::string_view &path, bool isExtension = false); +}; +} // namespace OHOS::FileManagement::Backup +#endif // OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_dir.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_dir.h new file mode 100644 index 00000000..27762942 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_dir.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_DIR_H +#define OHOS_FILEMGMT_BACKUP_B_DIR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "errors.h" + +namespace OHOS::FileManagement::Backup { +class BDir { +public: + /** + * @brief 读取指定目录下所有文件(非递归) + * + * @param 目录 + * @return 错误码、文件名数组 + */ + static std::tuple> GetDirFiles(const std::string &path); + + /** + * @brief 从给定的includes和excludes目录及文件中获取所有有用大文件和其链接文件的集合 + * + * @param includes 需要包含的文件及目录集合 + * @param excludes 需要排除的文件及目录集合 + * @return 错误码、大文件名集合 + */ + static std::pair> GetBigFiles(const std::vector &includes, + const std::vector &excludes); + + /** + * @brief Get the Dirs object + * + * @param paths 目录集合可带有通配符路径 + * @return std::vector 目录集合 + */ + static std::vector GetDirs(const std::vector &paths); +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_DIR_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_file.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_file.h new file mode 100644 index 00000000..863f4ad4 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_filesystem/b_file.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_FILE_H +#define OHOS_FILEMGMT_BACKUP_B_FILE_H + +#include +#include + +#include "unique_fd.h" +#include "json/json.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +class BFile { +public: + /** + * @brief 一次性读取文件全部内容 + * + * @param fd 文件描述符 + * @return std::unique_ptr 文件全部内容,保证最后一个字节为'\0' + * @throw std::system_error IO异常 + */ + static std::unique_ptr ReadFile(const UniqueFd &fd); + + /** + * @brief linux sendfile 二次封装 + * @param outFd 参数是待写入内容的文件描述符 + * @param inFd 参数是待读出内容的文件描述符 + * @throw std::system_error IO异常 + */ + static void SendFile(int outFd, int inFd); + + /** + * @brief linux write 二次封装 + * @param fd 参数是待写入内容的文件描述符 + * @param str 待写入文件的字符串 + * @throw std::system_error IO异常 + */ + static void Write(const UniqueFd &fd, const string &str); + + /** + * @brief copy file from old path to new path + * + * @param from old path + * @param to new path + * @return true copy succeess + * @return false some error occur + */ + static bool CopyFile(const string &from, const string &to); + +private: +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_FILE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_hilog/filemgmt_libhilog.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_hilog/filemgmt_libhilog.h new file mode 100644 index 00000000..6ed1f2d2 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_hilog/filemgmt_libhilog.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMGMT_LIBHILOG_H +#define FILEMGMT_LIBHILOG_H + +#include "hilog/log.h" + +#include + +namespace OHOS { +#ifndef LOG_DOMAIN +#define LOG_DOMAIN 0xD001600 +#endif + +#ifndef LOG_TAG +#define LOG_TAG "FileManagement" +#endif + +static constexpr HiviewDFX::HiLogLabel FILEMGMT_LOG_LABEL = {LOG_CORE, LOG_DOMAIN, LOG_TAG}; + +#if defined __FILE_NAME__ +#define FILEMGMT_FILE_NAME __FILE_NAME__ +#else +#include +#define FILEMGMT_FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +#endif + +#define FILEMGMT_PRINT_LOG(Level, fmt, ...) \ + HiviewDFX::HiLog::Level(FILEMGMT_LOG_LABEL, "[%{public}s:%{public}d->%{public}s] " fmt, FILEMGMT_FILE_NAME, \ + __LINE__, __FUNCTION__, ##__VA_ARGS__) + +#define HILOGD(fmt, ...) FILEMGMT_PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +#define HILOGI(fmt, ...) FILEMGMT_PRINT_LOG(Info, fmt, ##__VA_ARGS__) +#define HILOGW(fmt, ...) FILEMGMT_PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +#define HILOGE(fmt, ...) FILEMGMT_PRINT_LOG(Error, fmt, ##__VA_ARGS__) +#define HILOGF(fmt, ...) FILEMGMT_PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +} // namespace OHOS + +#endif // FILEMGMT_LIBHILOG_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_cached_entity.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_cached_entity.h new file mode 100644 index 00000000..8413c561 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_cached_entity.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_JSON_CACHED_ENTITY_H +#define OHOS_FILEMGMT_BACKUP_B_JSON_CACHED_ENTITY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_file.h" +#include "b_json/b_json_entity.h" +#include "filemgmt_libhilog.h" +#include "unique_fd.h" +#include "json/json.h" + +namespace OHOS::FileManagement::Backup { +template +class BJsonCachedEntity { +public: + /** + * @brief 获取结构化对象 + * + * @return T 结构化对象(即实体) + */ + T Structuralize() + { + static_assert(!std::is_default_constructible_v); + static_assert(!std::is_base_of_v); + return T(obj_); + } + + /** + * @brief 持久化JSon对象并完成 + * + * @throw std::system_error IO异常 + */ + void Persist() + { + Json::StreamWriterBuilder builder; + const std::string jsonFileContent = Json::writeString(builder, obj_); + HILOGI("Try to persist a Json object, whose content reads: %{public}s", jsonFileContent.c_str()); + + BFile::Write(srcFile_, jsonFileContent); + } + + /** + * @brief 从文件中重新加载JSon对象 + * + * @throw std::system_error IO异常或解析异常 + */ + int ReloadFromFile() + { + Json::CharReaderBuilder builder; + std::unique_ptr const jsonReader(builder.newCharReader()); + Json::Value jValue; + std::string errs; + std::unique_ptr rawBuf = BFile::ReadFile(srcFile_); + std::string_view sv(rawBuf.get()); + + if (sv.empty()) { + HILOGI("This Json file is empty"); + return 0; + } + + bool res = jsonReader->parse(sv.data(), sv.data() + sv.length(), &jValue, &errs); + if (!res || !errs.empty()) { + return BError(BError::Codes::UTILS_INVAL_JSON_ENTITY, errs).GetCode(); + } + + obj_ = std::move(jValue); + return 0; + } + + /** + * @brief 根据字符串重新加载JSon对象 + * + * @throw std::system_error IO异常或解析异常 + */ + void ReloadFromString(std::string_view sv) + { + Json::CharReaderBuilder builder; + std::unique_ptr const jsonReader(builder.newCharReader()); + Json::Value jValue; + std::string errs; + + bool res = jsonReader->parse(sv.data(), sv.data() + sv.length(), &jValue, &errs); + if (!res || !errs.empty()) { + throw BError(BError::Codes::UTILS_INVAL_JSON_ENTITY, errs); + } + + obj_ = std::move(jValue); + } + + /** + * @brief 获取JSon文件的文件描述符 + * + * @return UniqueFd& + */ + UniqueFd &GetFd() + { + return srcFile_; + } + +public: + /** + * @brief 构造方法,要求T必须具备T(Json::Value&)构造函数 + * + * @param fd 用于加载/持久化JSon对象的文件 + */ + explicit BJsonCachedEntity(UniqueFd fd) : srcFile_(std::move(fd)), entity_(std::ref(obj_)) + { + struct stat stat = {}; + if (fstat(srcFile_, &stat) == -1) { + std::stringstream ss; + ss << std::generic_category().message(errno) << " with fd eq" << srcFile_.Get(); + BError(BError::Codes::UTILS_INVAL_JSON_ENTITY, ss.str()); + return; + } + + (void)ReloadFromFile(); + } + + /** + * @brief 构造方法,要求T必须具备T(Json::Value&, std::any)构造函数 + * + * @param sv 用于加载/持久化JSon对象的字符串 + * @param option 任意类型对象 + */ + explicit BJsonCachedEntity(std::string_view sv, std::any option = std::any()) : entity_(std::ref(obj_)) + { + ReloadFromString(entity_.GetJSonSource(sv, option)); + } + +private: + UniqueFd srcFile_; + Json::Value obj_; + T entity_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_JSON_CACHED_ENTITY_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity.h new file mode 100644 index 00000000..c3a3e1f6 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_H +#define OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_H + +#include +#include +#include + +#include "json/json.h" + +namespace OHOS::FileManagement::Backup { +class BJsonEntity { +public: + /** + * @brief 获取JSon数据源 + * + * @param jsonFromRealWorld 直接来自真实用户场景的配置文件(即,非override配置) + * @param option 任意类型对象 + * @return std::string 取决于具体情况的配置文件 + */ + std::string GetJSonSource(std::string_view jsonFromRealWorld, std::any option = std::any()) + { + return std::string(jsonFromRealWorld); + } + +public: + /** + * @brief 构造方法,具备T(Json::Value&, std::any)能力的构造函数 + * + * @param obj Json对象引用 + * @param option 任意类型对象 + */ + explicit BJsonEntity(Json::Value &obj, std::any option = std::any()) : obj_(obj), option_(option) {} + BJsonEntity() = delete; + virtual ~BJsonEntity() = default; + +protected: + Json::Value &obj_; + std::any option_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_caps.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_caps.h new file mode 100644 index 00000000..9ab7bc21 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_caps.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_CAPS_H +#define OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_CAPS_H + +#include "b_json/b_json_cached_entity.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +class BJsonEntityCaps : public BJsonEntity { +public: + struct BundleInfo { + std::string name; + uint32_t versionCode; + std::string versionName; + int64_t spaceOccupied; + bool allToBackup; + std::string extensionName; + bool needToInstall {false}; + }; + +public: + void SetSystemFullName(std::string systemFullName) + { + obj_["systemFullName"] = systemFullName; + } + + void SetDeviceType(std::string deviceType) + { + obj_["deviceType"] = deviceType; + } + + void SetBundleInfos(std::vector bundleInfos) + { + if (obj_.isMember("bundleInfos")) { + obj_["bundleInfos"].clear(); + } + for (const auto &item : bundleInfos) { + Json::Value arrObj; + arrObj["name"] = item.name; + arrObj["versionCode"] = item.versionCode; + arrObj["versionName"] = item.versionName; + arrObj["spaceOccupied"] = item.spaceOccupied; + arrObj["allToBackup"] = item.allToBackup; + arrObj["extensionName"] = item.extensionName; + arrObj["needToInstall"] = item.needToInstall; + obj_["bundleInfos"].append(arrObj); + } + } + + std::string GetSystemFullName() + { + if (!obj_ || !obj_.isMember("systemFullName") || !obj_["systemFullName"].isString()) { + HILOGI("Failed to get field systemFullName"); + return ""; + } + + return obj_["systemFullName"].asString(); + } + + std::string GetDeviceType() + { + if (!obj_ || !obj_.isMember("deviceType") || !obj_["deviceType"].isString()) { + HILOGI("Failed to get field deviceType"); + return ""; + } + + return obj_["deviceType"].asString(); + } + + std::vector GetBundleInfos() + { + if (!obj_ || !obj_.isMember("bundleInfos") || !obj_["bundleInfos"].isArray()) { + HILOGI("Failed to get field get bundleInfos"); + return {}; + } + std::vector bundleInfos; + for (const auto &item : obj_["bundleInfos"]) { + if (!item || !item["name"].isString() || !item["versionCode"].isUInt() || !item["versionName"].isString() || + !item["spaceOccupied"].isInt64() || !item["allToBackup"].isBool() || + !item["extensionName"].isString() || !item["needToInstall"].isBool()) { + HILOGI("Failed to get field bundleInfos, type error"); + return {}; + } + bundleInfos.emplace_back(BundleInfo {item["name"].asString(), item["versionCode"].asUInt(), + item["versionName"].asString(), item["spaceOccupied"].asInt64(), + item["allToBackup"].asBool(), item["extensionName"].asString(), + item["needToInstall"].asBool()}); + } + return bundleInfos; + } + +public: + /** + * @brief 构造方法,具备T(Json::Value&, std::any)能力的构造函数 + * + * @param obj Json对象引用 + * @param option 任意类型对象 + */ + explicit BJsonEntityCaps(Json::Value &obj, std::any option = std::any()) : BJsonEntity(obj, option) + { + SetBundleInfos(GetBundleInfos()); + } + + BJsonEntityCaps() = delete; + ~BJsonEntityCaps() override = default; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_CAPS_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_ext_manage.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_ext_manage.h new file mode 100644 index 00000000..a322a559 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_ext_manage.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXT_MANAGE_H +#define OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXT_MANAGE_H + +#include +#include +#include +#include + +#include "b_json/b_json_cached_entity.h" +#include "json/json.h" + +namespace OHOS::FileManagement::Backup { +class BJsonEntityExtManage : public BJsonEntity { +public: + /** + * @brief 设置索引文件 + * + * @param info std::map> + */ + void SetExtManage(const map> &info) const; + + /** + * @brief 获取索引文件 + * + * @return std::set + */ + std::set GetExtManage() const; + + /** + * @brief 获取索引文件及详细信息 + * + * @return map> + */ + std::map> GetExtManageInfo() const; + + /** + * @brief Set the hard link Information + * + * @param origin 原始文件名 + * @param hardLinks 硬链接文件名 + * @return true 设置成功 + * @return false 设置失败 + */ + bool SetHardLinkInfo(const std::string origin, const std::set hardLinks); + + /** + * @brief Get the hard link Information + * + * @param origin 原始文件名 + * @return const 硬链接集合 + */ + const std::set GetHardLinkInfo(const string origin); + +public: + /** + * @brief 构造方法,具备T(Json::Value&, std::any)能力的构造函数 + * + * @param obj Json对象引用 + * @param option 任意类型对象 + */ + explicit BJsonEntityExtManage(Json::Value &obj, std::any option = std::any()) : BJsonEntity(obj, option) {} +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXT_MANAGE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_extension_config.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_extension_config.h new file mode 100644 index 00000000..b79dd06a --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_json/b_json_entity_extension_config.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXTENSION_CONFIG_H +#define OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXTENSION_CONFIG_H + +#include +#include + +#include "b_json/b_json_cached_entity.h" +#include "json/json.h" + +namespace OHOS::FileManagement::Backup { +class BJsonEntityExtensionConfig : public BJsonEntity { +public: + /** + * @brief 从JSon对象中通过includes字段获取待备份目录模式串清单 + * + * @return 待备份目录模式串清单 + * @note 如果用户没有配置该字段,则返回默认打包目录{@link BConstants::PATHES_TO_BACKUP} + * @note 如果用户配置了空数组,则返回""表示生成空打包文件 + */ + std::vector GetIncludes() const; + + /** + * @brief 从JSon对象中获取排除目录列表 + * + * @return 排除目录 + */ + std::vector GetExcludes() const; + + /** + * @brief 从JSon对象中获取备份恢复权限 + * + * @return 备份权限 + */ + bool GetAllowToBackupRestore() const; + +public: + std::string GetJSonSource(std::string_view jsonFromRealWorld, std::any option); + +public: + /** + * @brief 构造方法,具备T(Json::Value&, std::any)能力的构造函数 + * + * @param obj Json对象引用 + * @param option 任意类型对象 + */ + explicit BJsonEntityExtensionConfig(Json::Value &obj, std::any option = std::any()) : BJsonEntity(obj, option) {} +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_JSON_ENTITY_EXTENSION_CONFIG_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_ohos/startup/backup_para.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_ohos/startup/backup_para.h new file mode 100644 index 00000000..74d4e848 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_ohos/startup/backup_para.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_BACKUP_PARA_H +#define OHOS_FILEMGMT_BACKUP_BACKUP_PARA_H + +namespace OHOS::FileManagement::Backup { +class BackupPara { +public: + /** + * @brief 获取backup.para配置项backup.debug.overrideExtensionConfig的值 + * + * @return 获取的配置项backup.debug.overrideExtensionConfig值为true时则返回true,否则返回false + */ + bool GetBackupDebugOverrideExtensionConfig(); +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_BACKUP_PARA_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_cwd.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_cwd.h new file mode 100644 index 00000000..3d352136 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_cwd.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_GUARD_CWD_H +#define OHOS_FILEMGMT_BACKUP_B_GUARD_CWD_H + +/** + * @file b_cwd_guard.h + * @brief 异常安全的临时变更目录方法 + * + */ + +#include + +#include "nocopyable.h" + +namespace OHOS::FileManagement::Backup { +class BGuardCwd final : protected NoCopyable { +public: + /** + * @brief 构造器,其中会把当前目录变更为目标目录 + * + * @param tgtDir 目标目录 + */ + explicit BGuardCwd(std::string_view tgtDir); + + /** + * @brief 析构器,其中会把目标目录恢复为当前目录 + * + */ + ~BGuardCwd() final; + +private: + BGuardCwd() = delete; + char *pwd_ {nullptr}; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_GUARD_CWD_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_signal.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_signal.h new file mode 100644 index 00000000..0ff4565f --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_guard_signal.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_GUARD_SIGNAL_H +#define OHOS_FILEMGMT_BACKUP_B_GUARD_SIGNAL_H + +/** + * @file b_guard_signal.h + * @brief 异常安全的临时调整信号处理程序方法 + * + */ + +#include + +#include "nocopyable.h" + +namespace OHOS::FileManagement::Backup { +class BGuardSignal final : protected NoCopyable { +public: + /** + * @brief 构造器,其中会把给定信号的处理程序重置为默认值 + * + * @param sig 给定信号 + */ + explicit BGuardSignal(int sig); + + /** + * @brief 析构器,其中会还原给定信号的处理程序 + * + */ + ~BGuardSignal() final; + +private: + BGuardSignal() = delete; + sighandler_t prevHandler_ {nullptr}; + int sig_ {-1}; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_GUARD_SIGNAL_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_multiuser.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_multiuser.h new file mode 100644 index 00000000..02d0fbe5 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_multiuser.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_MULTIUSER_H +#define OHOS_FILEMGMT_BACKUP_B_MULTIUSER_H + +#include "b_resources/b_constants.h" + +namespace OHOS::FileManagement::Backup { +class BMultiuser { +public: + struct UidReadOut { + int userId; + int appId; + }; + +public: + static UidReadOut ParseUid(int uid) + { + return UidReadOut { + .userId = uid / BConstants::SPAN_USERID_UID, + .appId = uid % BConstants::SPAN_USERID_UID, + }; + } +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_MULTIUSER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_process.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_process.h new file mode 100644 index 00000000..c149dc18 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_process/b_process.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_PROCESS_H +#define OHOS_FILEMGMT_BACKUP_B_PROCESS_H + +#include +#include +#include +#include + +#include "errors.h" +#include "nocopyable.h" + +namespace OHOS::FileManagement::Backup { +class BProcess final : protected NoCopyable { +public: + /** + * @brief 执行一个命令并同步等待执行结果 + * + * @param argv 命令参数表 + * Parameter one is the command name represented by the absolute path. + * After that, parameter indicates the corresponding command parameter. + * Finally,nullptr does not need to be appended. + * + * @param DetectFatalLog 回调函数,用来对命令的stderr输出错误信息做进一步处理,检测是否发生了严重错误等。 + * + * @return 回调函数返回值,命令执行结果 + * + * @throw BError(UTILS_INVAL_PROCESS_ARG) 系统调用异常(子进程启动失败、waitpid调用失败) + * + * @throw BError(UTILS_INTERRUPTED_PROCESS) 系统调用异常(pipe调用失败、dup2调用失败、子进程被信号终止) + */ + static std::tuple ExecuteCmd(std::vector argv, + std::function DetectFatalLog = nullptr); + +private: + BProcess() = delete; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_PROCESS_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_resources/b_constants.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_resources/b_constants.h new file mode 100644 index 00000000..0287ca83 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_resources/b_constants.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_CONSTANTS_H +#define OHOS_FILEMGMT_BACKUP_B_CONSTANTS_H + +#include +#include +#include +#include +#include + +namespace OHOS::FileManagement::Backup::BConstants { + +static inline const char *EXTENSION_ACTION_PARA = "extensionAction"; +static inline const char *EXTENSION_RESTORE_TYPE_PARA = "restoreType"; +static inline const char *EXTENSION_VERSION_CODE_PARA = "versionCode"; +static inline const char *EXTENSION_VERSION_NAME_PARA = "versionName"; + +enum class ExtensionAction { + INVALID = 0, + BACKUP = 1, + RESTORE = 2, +}; + +enum ServiceSchedAction { + WAIT = 0, + INSTALLING = 1, + START, + RUNNING, + FINISH, +}; + +enum EntryKey { + SUPER_LONG_PATH = 0, + SUPER_LONG_LINK_PATH, + SUPER_LONG_SIZE, +}; + +constexpr int SPAN_USERID_UID = 20000000; +constexpr int SYSTEM_UID = 0; +constexpr int XTS_UID = 1; +constexpr int DEFAULT_USER_ID = 100; +constexpr int BACKUP_UID = 1089; +constexpr int EXTENSION_THREAD_POOL_COUNT = 1; +constexpr int BACKUP_LOADSA_TIMEOUT_MS = 4000; + +constexpr int DECIMAL_BASE = 10; // 十进制基数 + +constexpr int HEADER_SIZE = 512; // 打包文件头部Header结构体大小 +constexpr int BLOCK_SIZE = 512; // 打包文件数据段尾部补充的全零字节块上限大小 +constexpr int BLOCK_PADDING_SIZE = 1024; // 打包文件尾部追加的全零字节块大小 +constexpr off_t BIG_FILE_BOUNDARY = 1024 * 1024 * 1024; // 大文件边界 +constexpr unsigned long BIG_FILE_NAME_SIZE = 16; // 大文件名长度(hash处理) + +// 打包文件头部Header结构体各字段数组/字符串大小。 +constexpr int PATHNAME_MAX_SIZE = 100; +constexpr int MODE_MAX_SIZE = 8; +constexpr int UGID_MAX_SIZE = 8; +constexpr int FILESIZE_MAX_SIZE = 12; +constexpr int TIME_MAX_SIZE = 12; +constexpr int CHKSUM_MAX_SIZE = 8; +constexpr int LINKNAME_MAX_SIZE = 100; +constexpr int MAGIC_SIZE = 6; +constexpr int VERSION_SIZE = 2; +constexpr int UGNAME_MAX_SIZE = 32; +constexpr int DEV_MAX_SIZE = 8; +constexpr int PREFIX_SIZE = 155; +constexpr int PADDING_SIZE = 12; + +// 读取backup.para字段值的最大长度 +constexpr uint32_t BACKUP_PARA_VALUE_MAX = 5; + +// SA THREAD_POOL 最大线程数 +constexpr int SA_THREAD_POOL_COUNT = 1; +// extension 最大启动数 +constexpr int EXT_CONNECT_MAX_COUNT = 3; +// SA 启动 extension 等待连接最大时间 +constexpr int EXT_CONNECT_MAX_TIME = 15000; + +// 打包文件头部Header结构体fileSize字段最大值。 +constexpr off_t FILESIZE_MAX = 077777777777; + +// 打包文件头部Header结构体typeFlag字段值。 +constexpr char TYPEFLAG_REGULAR_FILE = '0'; +constexpr char TYPEFLAG_SYMBOLIC_LINK = '2'; +constexpr char TYPEFLAG_DIRECTORY = '5'; +constexpr char TYPEFLAG_EXTENDED = 'x'; + +// 打包文件扩展数据段字段值。 +static inline std::string ENTRY_NAME_LINKPATH = "linkpath"; +static inline std::string ENTRY_NAME_PATH = "path"; +static inline std::string ENTRY_NAME_SIZE = "size"; + +// backup.para内配置项的名称,改配置项值为true时可在不更新hap包的情况下,可以读取包管理元数据配置文件的内容 +static inline std::string BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY = "backup.debug.overrideExtensionConfig"; + +// 应用备份数据暂存路径 +static inline std::string_view SA_BUNDLE_BACKUP_BACKUP = "/backup/"; +static inline std::string_view SA_BUNDLE_BACKUP_RESTORE = "/restore/"; +static inline std::string_view SA_BUNDLE_BACKUP_TMP_DIR = "/tmp/"; +static inline std::string_view BACKUP_TOOL_RECEIVE_DIR = "/data/backup/received/"; +static inline std::string_view PATH_BUNDLE_BACKUP_HOME = "/data/storage/el2/backup"; +static inline std::string_view BACKUP_TOOL_LINK_DIR = "/data/backup"; +static inline std::string_view BACKUP_TOOL_INSTALL_DIR = "/data/backup/install/"; + +// 多用户场景应用备份数据路径 +static inline std::string GetSaBundleBackupDir(int32_t userId) +{ + std::string str; + str.append("/data/service/el2/"); + str.append(std::to_string(userId)); + str.append("/backup/bundles/"); + return str; +} + +static inline std::string GetSaBundleBackupRootDir(int32_t userId) +{ + std::string str; + str.append("/data/service/el2/"); + str.append(std::to_string(userId)); + str.append("/backup/backup_sa/"); + return str; +} + +static inline std::string GetSaBundleBackupToolDir(int32_t userId) +{ + std::string str; + str.append("/data/service/el2/"); + str.append(std::to_string(userId)); + str.append("/backup/backup_tool/"); + return str; +} + +// 备份恢复配置文件暂存路径 +static inline std::string_view BACKUP_CONFIG_EXTENSION_PATH = "/data/storage/el2/base/temp/"; + +// 应用备份恢复所需的索引文件 +static inline std::string_view EXT_BACKUP_MANAGE = "manage.json"; + +// 包管理元数据配置文件 +static inline std::string_view BACKUP_CONFIG_JSON = "backup_config.json"; + +// 恢复应用安装包URL判断 +static inline std::string_view RESTORE_INSTALL_PATH = "/data/storage/el2/restore/bundle.hap"; + +// 双生单场景默认的版本信息 +constexpr int DEFAULT_VERSION_CODE = 0; +static inline std::string_view DEFAULT_VERSION_NAME = "0.0.0.0"; + +// 应用默认备份的目录,其均为相对根路径的路径。为避免模糊匹配,务必以斜线为结尾。 +static inline std::array PATHES_TO_BACKUP = { + "data/storage/el2/database/", + "data/storage/el2/base/files/", + "data/storage/el2/base/preferences/", + "data/storage/el2/base/haps/*/database/", + "data/storage/el2/base/haps/*/files/", + "data/storage/el2/base/haps/*/preferences/", +}; +} // namespace OHOS::FileManagement::Backup::BConstants + +#endif // OHOS_FILEMGMT_BACKUP_B_CONSTANTS_H diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_cmdline.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_cmdline.h new file mode 100644 index 00000000..d00a2823 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_cmdline.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_TARBALL_CMDLINE_H +#define OHOS_FILEMGMT_BACKUP_B_TARBALL_CMDLINE_H + +#include +#include +#include + +#include "nocopyable.h" + +namespace OHOS::FileManagement::Backup { +class BTarballCmdline final : protected NoCopyable { +public: + void Tar(std::string_view root, std::vector includes, std::vector excludes); + void Untar(std::string_view root); + +public: + BTarballCmdline(std::string_view tarballDir, std::string_view tarballName); + +private: + std::string tarballDir_; + std::string tarballName_; + std::string tarballPath_; +}; +} // namespace OHOS::FileManagement::Backup +#endif // OHOS_FILEMGMT_BACKUP_B_TARBALL_CMDLINE_H diff --git a/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_factory.h b/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_factory.h new file mode 100644 index 00000000..728c91c1 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/include/b_tarball/b_tarball_factory.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_TARBALL_FACTORY_H +#define OHOS_FILEMGMT_BACKUP_B_TARBALL_FACTORY_H + +/** + * @file b_tarball.h + * @brief 使用指定实现打包/解包,本层在进行打包/解包前还负责防御路径穿越攻击 + * + */ +#include +#include +#include + +#include "nocopyable.h" + +namespace OHOS::FileManagement::Backup { +class BTarballFactory final : protected NoCopyable { +public: + /** + * @brief 打包器仿函数集合 + * 当前迫于时间所限,不得不采用命令行实现。后续必然要实现自研打包协议,从而满足在同一个进程进行打包的诉求。 + * 在降低调用成本后,就可以实现逐个向tarball追加文件的append方法。append方法是优化方法,和tar二选一即可。 + * 然而纯虚函数必须得在子类实现,这一性质使得基于继承的设计模式无法方便地选择合适的打包方法,为了解决这个问题, + * 这里采用组合的方式实现。现在在外层简单地判断相应仿函数是否为空,就知道如何进行选择了。 + */ + struct Impl { + /** + * @brief 打包 + * + * @param _1 进入该参数指定路径打包文件。 + * An absolute path is required. + * @param _2 _1中需要打包的路径。 + * 要求输入相对路径,除禁止路径穿越外无其余要求,不填默认全部打包 + * @param _3 The part that does not need to be packed in the path to be packed. + * 要求输入相对路径,路径穿越场景无实际意义因此予以禁止。可用于排除部分子目录 + */ + std::function, std::vector)> tar; + + /** + * @brief 解包 + * + * @param _1 用于存储解包文件的根目录 + * An absolute path is required. + */ + std::function untar; + }; + +public: + /** + * @brief 打包器工厂方法 + * + * @param implType 打包器实现方式,可选择'cmdline' + * @param tarballPath Absolute path of the file package。Cannot contain extra slashes, must be suffixed with .tar + * @return std::unique_ptr 打包器仿函数集合 + */ + static std::unique_ptr Create(std::string_view implType, std::string_view tarballPath); + +public: + BTarballFactory() = delete; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_TARBALL_FACTORY_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/rust/src/lib.rs b/mock/innerkits/filemanagement/app_file_service/utils/rust/src/lib.rs new file mode 100644 index 00000000..2f2f697f --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/rust/src/lib.rs @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! Rust utils for cxx +#[cxx::bridge] +mod ffi{ + #![allow(dead_code)] + extern "Rust"{ + fn canonicalize(path: String) -> Result; + } +} + +use std::fs; +use std::io::{Error, ErrorKind}; + +fn canonicalize(path: String) -> Result { + match fs::canonicalize(path) { + Ok(abs_path) => { + match abs_path.to_str() { + Some(path) => Ok(path.to_string()), + None => Err(Error::new(ErrorKind::Other, "canonicalize failed")), + } + }, + Err(_) => Err(Error::new(ErrorKind::Other, "canonicalize failed")), + } +} \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_encryption/b_encryption.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_encryption/b_encryption.cpp new file mode 100644 index 00000000..98bad7f1 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_encryption/b_encryption.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_encryption/b_encryption.h" + +namespace OHOS::FileManagement::Backup::BEncryption { +unsigned int CalculateChksum(const char *byteBlock, int blockSize) +{ + unsigned int chksum = 0U; + for (int i = 0; i < blockSize; ++i) { + chksum += 0xFF & *(byteBlock + i); + } + return chksum; +} +} // namespace OHOS::FileManagement::Backup::BEncryption \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_error.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_error.cpp new file mode 100644 index 00000000..59443acf --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_error.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_error/b_error.h" + +#include +#include +#include + +#include "dfx_dump_catcher.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +string BError::WrapMessageWithExtraInfos(const char *fileName, + int lineNo, + const char *functionName, + Codes code, + const vector &msgs) const +{ + stringstream ss; + ss << '[' << fileName << ':' << lineNo << " -> " << functionName << ']' << ' '; + for (size_t i = 0; i < msgs.size(); ++i) { + ss << msgs[i]; + if (i != msgs.size() - 1) { + ss << ". "; + } + } + + if (code != Codes::OK) { + string msg; + HiviewDFX::DfxDumpCatcher().DumpCatch(getpid(), syscall(SYS_gettid), msg); + ss << endl << msg; + } + + string res = ss.str(); + HiviewDFX::HiLog::Error(FILEMGMT_LOG_LABEL, "%{public}s", res.c_str()); + return res; +} + +int BError::GetCode() const +{ + int code = static_cast(GetRawCode()); + if (errCodeTable_.find(code) != errCodeTable_.end()) { + return errCodeTable_.at(code); + } + HILOGE("Unknown code : %{public}d", code); + return BackupErrorCode::E_UKERR; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_excep_utils.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_excep_utils.cpp new file mode 100644 index 00000000..5a6ad2f9 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_error/b_excep_utils.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_error/b_excep_utils.h" + +#include + +#include "b_resources/b_constants.h" +#include "cxx.h" +#include "lib.rs.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +void BExcepUltils::VerifyPath(const string_view &path, bool isExtension) +{ + try { + auto ret = canonicalize(path.data()); + string absPath = ret.c_str(); + if (isExtension && + absPath.find(string(BConstants::PATH_BUNDLE_BACKUP_HOME) + .append(BConstants::SA_BUNDLE_BACKUP_RESTORE)) == std::string::npos) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path, not in backup restore path"); + } + } catch (const rust::Error &e) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path"); + } +} +} // namespace OHOS::FileManagement::Backup diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_dir.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_dir.cpp new file mode 100644 index 00000000..93eb3eb6 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_dir.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_filesystem/b_dir.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_resources/b_constants.h" +#include "directory_ex.h" +#include "errors.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +pair> GetDirFilesDetail(const string &path, bool recursion, off_t size = -1) +{ + map files; + unique_ptr> dir = {opendir(path.c_str()), closedir}; + if (!dir) { + HILOGE("Invalid directory path: %{private}s", path.c_str()); + return {BError(errno).GetCode(), files}; + } + + struct dirent *ptr = nullptr; + while (!!(ptr = readdir(dir.get()))) { + // current dir OR parent dir + if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) { + continue; + } else if (ptr->d_type == DT_DIR) { + if (!recursion) { + continue; + } + + auto [errCode, subfiles] = + GetDirFilesDetail(IncludeTrailingPathDelimiter(path) + string(ptr->d_name), recursion, size); + if (errCode != 0) { + return {errCode, files}; + } + files.merge(subfiles); + } else if (ptr->d_type == DT_LNK) { + continue; + } else { + struct stat sta = {}; + string fileName = IncludeTrailingPathDelimiter(path) + string(ptr->d_name); + if (stat(fileName.data(), &sta) == -1) { + continue; + } + if (sta.st_size < size) { + continue; + } + HILOGI("Find big file"); + files.try_emplace(fileName, sta); + } + } + + return {BError(BError::Codes::OK).GetCode(), files}; +} + +tuple> BDir::GetDirFiles(const string &path) +{ + vector files; + unique_ptr> dir = {opendir(path.c_str()), closedir}; + if (!dir) { + HILOGE("Invalid directory path: %{private}s", path.c_str()); + return {BError(errno).GetCode(), files}; + } + + struct dirent *ptr = nullptr; + while (!!(ptr = readdir(dir.get()))) { + // current dir OR parent dir + if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) { + continue; + } else if (ptr->d_type == DT_DIR) { + continue; + } else { + files.push_back(IncludeTrailingPathDelimiter(path) + string(ptr->d_name)); + } + } + + return {BError(BError::Codes::OK).GetCode(), files}; +} + +static set ExpandPathWildcard(const vector &vec) +{ + unique_ptr> gl {new glob_t, [](glob_t *ptr) { globfree(ptr); }}; + *gl = {}; + + int flags = GLOB_DOOFFS | GLOB_MARK; + for (const string &pattern : vec) { + if (!pattern.empty()) { + glob(pattern.data(), flags, NULL, gl.get()); + flags |= GLOB_APPEND; + } + } + + set expandPath, filteredPath; + for (size_t i = 0; i < gl->gl_pathc; ++i) { + expandPath.emplace(gl->gl_pathv[i]); + } + + for (auto it = expandPath.begin(); it != expandPath.end(); ++it) { + filteredPath.insert(*it); + if (*it->rbegin() != '/') { + continue; + } + auto jt = it; + for (++jt; jt != expandPath.end() && (jt->find(*it) == 0); ++jt) { + } + + it = --jt; + } + + return filteredPath; +} + +pair> BDir::GetBigFiles(const vector &includes, + const vector &excludes) +{ + set inc = ExpandPathWildcard(includes); + + map incFiles; + for (const auto &item : inc) { + auto [errCode, files] = + OHOS::FileManagement::Backup::GetDirFilesDetail(item, true, BConstants::BIG_FILE_BOUNDARY); + if (errCode == 0) { + int32_t num = static_cast(files.size()); + HILOGI("found big files. total number is : %{public}d", num); + incFiles.merge(move(files)); + } + } + + auto isMatch = [](const vector &s, const string &str) -> bool { + if (str.empty()) { + return false; + } + for (const string &item : s) { + if (!item.empty() && (fnmatch(item.data(), str.data(), FNM_LEADING_DIR) == 0)) { + HILOGI("file %{public}s matchs exclude condition", str.c_str()); + return true; + } + } + return false; + }; + + map bigFiles; + for (const auto &item : incFiles) { + if (!isMatch(excludes, item.first)) { + HILOGI("file %{public}s matchs include condition and unmatchs exclude condition", item.first.c_str()); + bigFiles[item.first] = item.second; + } + } + int32_t num = static_cast(bigFiles.size()); + HILOGI("total number of big files is %{public}d", num); + return {ERR_OK, move(bigFiles)}; +} + +vector BDir::GetDirs(const vector &paths) +{ + vector wildcardPath(paths.begin(), paths.end()); + set inc = ExpandPathWildcard(wildcardPath); + vector dirs(inc.begin(), inc.end()); + return dirs; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_file.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_file.cpp new file mode 100644 index 00000000..aa8c3637 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_filesystem/b_file.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_filesystem/b_file.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +unique_ptr BFile::ReadFile(const UniqueFd &fd) +{ + if (lseek(fd, 0, SEEK_SET) == -1) { + throw BError(errno); + } + + struct stat stat = {}; + if (fstat(fd, &stat) == -1) { + throw BError(errno); + } + off_t fileSize = stat.st_size; + if (fileSize == 0) { + HILOGI("Deserialized an empty file"); + return make_unique(1); + } + + auto buf = make_unique(fileSize + 1); + if (read(fd, buf.get(), fileSize) == -1) { + throw BError(errno); + } + return buf; +} + +void BFile::SendFile(int outFd, int inFd) +{ + off_t offset = 0; + long ret = 0; + if (lseek(outFd, 0, SEEK_SET) == -1) { + throw BError(errno); + } + if (lseek(inFd, 0, SEEK_SET) == -1) { + throw BError(errno); + } + struct stat stat = {}; + if (fstat(inFd, &stat) == -1) { + throw BError(errno); + } + while ((ret = sendfile(outFd, inFd, &offset, stat.st_size)) > 0) { + }; + + if (ret == -1) { + throw BError(errno); + } + ret = ftruncate(outFd, offset); + if (ret == -1) { + throw BError(errno); + } +} + +void BFile::Write(const UniqueFd &fd, const string &str) +{ + int ret = pwrite(fd, str.c_str(), str.length(), 0); + if (ret == -1) { + throw BError(errno); + } + if (ftruncate(fd, ret) == -1) { + throw BError(errno); + } +} + +bool BFile::CopyFile(const string &from, const string &to) +{ + if (from == to) { + return true; + } + + try { + auto resolvedPath = make_unique(PATH_MAX); + if (!realpath(from.data(), resolvedPath.get())) { + HILOGI("failed to real path for the file %{public}s", from.c_str()); + return false; + } + string oldPath(resolvedPath.get()); + UniqueFd fdFrom(open(oldPath.data(), O_RDONLY)); + if (fdFrom == -1) { + HILOGE("failed to open the file %{public}s", from.c_str()); + throw BError(errno); + } + + unique_ptr> dir {strdup(to.data()), free}; + if (!dir) { + throw BError(errno); + } + if (!realpath(dirname(dir.get()), resolvedPath.get())) { + HILOGI("failed to real path for %{public}s", to.c_str()); + return false; + } + string newPath(resolvedPath.get()); + unique_ptr> name {strdup(to.data()), free}; + if (!name) { + throw BError(errno); + } + newPath.append("/").append(basename(name.get())); + UniqueFd fdTo(open(newPath.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); + if (fdTo == -1) { + HILOGE("failed to open the file %{public}s", to.c_str()); + throw BError(errno); + } + + SendFile(fdTo, fdFrom); + return true; + } catch (const BError &e) { + HILOGE("%{public}s", e.what()); + } catch (const exception &e) { + HILOGE("%{public}s", e.what()); + } catch (...) { + HILOGE(""); + } + return false; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_ipc/b_want_2_ext.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_ipc/b_want_2_ext.cpp new file mode 100644 index 00000000..9e34cbc9 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_ipc/b_want_2_ext.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_ipc/b_want_2_ext.h" + +#include + +#include "b_error/b_error.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +constexpr const char *PARA_EXT_ACTION = "extensionAction"; + +void BWant2Ext::Issue() const +{ +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_ext_manage.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_ext_manage.cpp new file mode 100644 index 00000000..9d5ccca9 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_ext_manage.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_json/b_json_entity_ext_manage.h" +#include "b_resources/b_constants.h" +#include "filemgmt_libhilog.h" +#include "json/value.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +Json::Value Stat2JsonValue(struct stat sta) +{ + Json::Value value; + + value["st_size"] = static_cast(sta.st_size); + value["st_atim"]["tv_sec"] = static_cast(sta.st_atim.tv_sec); + value["st_atim"]["tv_nsec"] = static_cast(sta.st_atim.tv_nsec); + value["st_mtim"]["tv_sec"] = static_cast(sta.st_mtim.tv_sec); + value["st_mtim"]["tv_nsec"] = static_cast(sta.st_mtim.tv_nsec); + + return value; +} + +struct stat JsonValue2Stat(const Json::Value &value) +{ + struct stat sta = {}; + + sta.st_size = value.isMember("st_size") ? value["st_size"].asInt64() : 0; + if (value.isMember("st_atim")) { + sta.st_atim.tv_sec = value["st_atim"].isMember("tv_sec") ? value["st_atim"]["tv_sec"].asInt64() : 0; + sta.st_atim.tv_nsec = value["st_atim"].isMember("tv_nsec") ? value["st_atim"]["tv_nsec"].asInt64() : 0; + } + if (value.isMember("st_mtim")) { + sta.st_mtim.tv_sec = value["st_mtim"].isMember("tv_sec") ? value["st_mtim"]["tv_sec"].asInt64() : 0; + sta.st_mtim.tv_nsec = value["st_mtim"].isMember("tv_nsec") ? value["st_mtim"]["tv_nsec"].asInt64() : 0; + } + + return sta; +} + +void BJsonEntityExtManage::SetExtManage(const map> &info) const +{ + obj_.clear(); + + vector vec(info.size(), false); + + auto FindLinks = [&vec](map>::const_iterator it, + unsigned long index) -> set { + if (it->second.second.st_dev == 0 || it->second.second.st_ino == 0) { + return {}; + } + + set lks; + auto item = it; + item++; + + for (auto i = index + 1; i < vec.size(); ++i, ++item) { + if (it->second.second.st_dev == item->second.second.st_dev && + it->second.second.st_ino == item->second.second.st_ino) { + vec[i] = true; + lks.insert(item->second.first); + } + } + return lks; + }; + + unsigned long index = 0; + for (auto item = info.begin(); item != info.end(); ++item, ++index) { + if (vec[index]) { + HILOGI("skipped file is %{public}s", item->first.c_str()); + continue; + } + HILOGI("file name is %{public}s", item->first.c_str()); + + Json::Value value; + value["fileName"] = item->first; + if (item->second.first == BConstants::RESTORE_INSTALL_PATH) { + throw BError(BError::Codes::UTILS_INVAL_JSON_ENTITY, "Failed to set ext manage, invalid path"); + } + value["information"]["path"] = item->second.first; + value["information"]["stat"] = Stat2JsonValue(item->second.second); + set lks = FindLinks(item, index); + for (const auto &lk : lks) { + value["hardlinks"].append(lk); + } + + obj_.append(value); + } +} + +set BJsonEntityExtManage::GetExtManage() const +{ + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return {}; + } + if (!obj_.isArray()) { + HILOGE("json object isn't an array"); + return {}; + } + + set info; + for (Json::Value &item : obj_) { + string fileName = item.isMember("fileName") ? item["fileName"].asString() : ""; + info.emplace(fileName); + } + return info; +} + +map> BJsonEntityExtManage::GetExtManageInfo() const +{ + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return {}; + } + if (!obj_.isArray()) { + HILOGE("json object isn't an array"); + return {}; + } + + map> info; + for (const Json::Value &item : obj_) { + string fileName = item.isMember("fileName") ? item["fileName"].asString() : ""; + + if (!item.isMember("information")) { + continue; + } + + struct stat sta = {}; + string path = item["information"].isMember("path") ? item["information"]["path"].asString() : ""; + if (path == BConstants::RESTORE_INSTALL_PATH) { + throw BError(BError::Codes::UTILS_INVAL_JSON_ENTITY, "Failed to get ext manage info, invalid path"); + } + if (item["information"].isMember("stat")) { + sta = JsonValue2Stat(item["information"]["stat"]); + } + + if (!fileName.empty() && !path.empty()) { + info.emplace(fileName, make_pair(path, sta)); + } + } + + return info; +} + +bool BJsonEntityExtManage::SetHardLinkInfo(const string origin, const set hardLinks) +{ + if (origin.empty()) { + HILOGE("origin file name can not empty"); + return false; + } + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return false; + } + if (!obj_.isArray()) { + HILOGE("json object isn't an array"); + return false; + } + + for (Json::Value &item : obj_) { + string fileName = item.isMember("fileName") ? item["fileName"].asString() : ""; + if (origin == fileName) { + for (const auto &lk : hardLinks) { + item["hardlinks"].append(lk); + } + return true; + } + } + + return false; +} + +const set BJsonEntityExtManage::GetHardLinkInfo(const string origin) +{ + if (origin.empty()) { + HILOGE("origin file name can not empty"); + return {}; + } + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return {}; + } + if (!obj_.isArray()) { + HILOGE("json object isn't an array"); + return {}; + } + + set hardlinks; + for (const Json::Value &item : obj_) { + string fileName = item.isMember("fileName") ? item["fileName"].asString() : ""; + if (origin == fileName) { + if (!(item.isMember("hardlinks") && item["hardlinks"].isArray())) { + break; + } + for (const auto &lk : item["hardlinks"]) { + hardlinks.emplace(lk.asString()); + } + } + } + + return hardlinks; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_extension_config.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_extension_config.cpp new file mode 100644 index 00000000..39fed928 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_json/b_json_entity_extension_config.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_json/b_json_entity_extension_config.h" + +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_file.h" +#include "b_ohos/startup/backup_para.h" +#include "b_resources/b_constants.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +vector BJsonEntityExtensionConfig::GetIncludes() const +{ + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return {BConstants::PATHES_TO_BACKUP.begin(), BConstants::PATHES_TO_BACKUP.end()}; + } + if (!obj_.isMember("includes")) { + HILOGE("'includes' field not found"); + return {BConstants::PATHES_TO_BACKUP.begin(), BConstants::PATHES_TO_BACKUP.end()}; + } + if (!obj_["includes"].isArray()) { + HILOGE("'includes' field must be an array"); + return {BConstants::PATHES_TO_BACKUP.begin(), BConstants::PATHES_TO_BACKUP.end()}; + } + + vector dirs; + for (auto &&item : obj_["includes"]) { + if (!item.isString()) { + HILOGE("Each item of array 'includes' must be of the type string"); + continue; + } + dirs.push_back(item.asString()); + } + + if (dirs.empty()) { + dirs.emplace_back(""); + } + return dirs; +} + +vector BJsonEntityExtensionConfig::GetExcludes() const +{ + if (!obj_) { + HILOGE("Uninitialized JSon Object reference"); + return {}; + } + if (!obj_.isMember("excludes")) { + HILOGE("'excludes' field not found"); + return {}; + } + if (!obj_["excludes"].isArray()) { + HILOGE("'excludes' field must be an array"); + return {}; + } + + vector dirs; + for (auto &&item : obj_["excludes"]) { + if (!item.isString()) { + HILOGE("Each item of array 'excludes' must be of the type string"); + return {}; + } + dirs.push_back(item.asString()); + } + return dirs; +} + +bool BJsonEntityExtensionConfig::GetAllowToBackupRestore() const +{ + if (!obj_ || !obj_.isMember("allowToBackupRestore") || !obj_["allowToBackupRestore"].isBool()) { + HILOGE("Failed to init field allowToBackupRestore"); + return false; + } + + return obj_["allowToBackupRestore"].asBool(); +} + +string BJsonEntityExtensionConfig::GetJSonSource(string_view jsonFromRealWorld, any option) +{ + if (!BackupPara().GetBackupDebugOverrideExtensionConfig()) { + return string(jsonFromRealWorld); + } + + /* Server for test case, the user function does not execute the following code. */ + if (!option.has_value()) { + if (getuid() == static_cast(BConstants::BACKUP_UID)) { + throw BError(BError::Codes::SA_INVAL_ARG, "Current process is not extension process"); + } + string jsonFilePath = string(BConstants::BACKUP_CONFIG_EXTENSION_PATH).append(BConstants::BACKUP_CONFIG_JSON); + return BFile::ReadFile(UniqueFd(open(jsonFilePath.c_str(), O_RDONLY))).get(); + } + + if (getuid() != static_cast(BConstants::BACKUP_UID)) { + throw BError(BError::Codes::SA_INVAL_ARG, "Current process is not service process"); + } + string bundleName; + try { + bundleName = any_cast(option); + } catch (const bad_any_cast &e) { + throw BError(BError::Codes::SA_INVAL_ARG, e.what()); + } + string jsonFilePath = string(BConstants::GetSaBundleBackupRootDir(BConstants::DEFAULT_USER_ID)). + append(bundleName). + append("/"). + append(BConstants::BACKUP_CONFIG_JSON); + return BFile::ReadFile(UniqueFd(open(jsonFilePath.c_str(), O_RDONLY))).get(); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_ohos/startup/backup_para.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_ohos/startup/backup_para.cpp new file mode 100644 index 00000000..2c7abcb5 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_ohos/startup/backup_para.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_ohos/startup/backup_para.h" + +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_resources/b_constants.h" +#include "filemgmt_libhilog.h" +#include "parameter.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +/** + * @brief 获取配置参数的值 + * + * @param key 配置参数的参数名 + * @param len 配置参数值的最大长度 + * @return 成功获取配置参数的值则返回true,失败则返回false;以及表示配置参数值的字符串 + */ +static tuple GetConfigParameterValue(const string &key, uint32_t len) +{ + int handle = static_cast(FindParameter(key.c_str())); + if (handle == -1) { + HILOGI("Fail to find parameter."); + return {false, ""}; + } + try { + unique_ptr buffer = make_unique(len + 1); + int res = GetParameterValue(handle, buffer.get(), len + 1); + if (res < 0) { + HILOGI("Fail to get parameter value."); + return {false, ""}; + } + return {true, buffer.get()}; + } catch (const bad_alloc &e) { + HILOGI("Fail to get parameter value: %{public}s.", e.what()); + return {false, ""}; + } +} + +bool BackupPara::GetBackupDebugOverrideExtensionConfig() +{ + auto [getCfgParaValSucc, value] = GetConfigParameterValue(BConstants::BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY, + BConstants::BACKUP_PARA_VALUE_MAX); + if (!getCfgParaValSucc) { + throw BError(BError::Codes::SA_INVAL_ARG, "Fail to get configuration parameter value of backup.para"); + } + return value == "true"; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_cwd.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_cwd.cpp new file mode 100644 index 00000000..c97136ee --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_cwd.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_process/b_guard_cwd.h" +#include "b_error/b_error.h" + +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; + +BGuardCwd::BGuardCwd(std::string_view tgtDir) +{ + pwd_ = getcwd(nullptr, 0); + if (!pwd_) { + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, "Out of memory"); + } + if (chdir(tgtDir.data())) { + std::free(pwd_); + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, std::generic_category().message(errno)); + } +} + +BGuardCwd::~BGuardCwd() +{ + chdir(pwd_); + free(pwd_); +} +} // namespace OHOS::FileManagement::Backup diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_signal.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_signal.cpp new file mode 100644 index 00000000..6d2c892e --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_guard_signal.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_process/b_guard_signal.h" + +#include + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; +BGuardSignal::BGuardSignal(int sig) : sig_(sig) +{ + prevHandler_ = signal(sig, SIG_DFL); + if (prevHandler_ == SIG_ERR) { + stringstream ss; + ss << "Invalid sigal " << sig << ", received error " << system_category().message(errno); + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, ss.str()); + } +} + +BGuardSignal::~BGuardSignal() +{ + if (signal(sig_, prevHandler_) == SIG_ERR) { + HILOGE("Failed to reset sig %{public}d", sig_); + } +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_process.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_process.cpp new file mode 100644 index 00000000..78b9226a --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_process/b_process.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_process/b_process.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_process/b_guard_signal.h" +#include "errors.h" +#include "filemgmt_libhilog.h" +#include "securec.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +static tuple WaitForChild(pid_t pid, + unique_ptr> pipeStream, + function DetectFatalLog) +{ + const int BUF_LEN = 1024; + auto buf = make_unique(BUF_LEN); + int status = 0; + + do { + regex reg("^\\W*$"); + while ((void)memset_s(buf.get(), BUF_LEN, 0, BUF_LEN), + fgets(buf.get(), BUF_LEN - 1, pipeStream.get()) != nullptr) { + if (regex_match(buf.get(), reg)) { + continue; + } + HILOGE("child process output error: %{public}s", buf.get()); + if (DetectFatalLog && DetectFatalLog(string_view(buf.get()))) { + return {true, EPERM}; + } + } + + if (waitpid(pid, &status, 0) == -1) { + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, generic_category().message(errno)); + } else if (WIFEXITED(status)) { + return {false, WEXITSTATUS(status)}; + } else if (WIFSIGNALED(status)) { + // 因某种信号中断获取状态 + // 异常机制存在问题,导致应用在正常的错误下Crash。为确保测试顺利展开,此处暂时屏蔽崩溃错误。 + HILOGE("some fatal errors occurred, child process is killed by a signal."); + return {true, EPERM}; + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + HILOGE("If you look at me, there are some fatal errors occurred!!!"); + return {true, EPERM}; +} + +tuple BProcess::ExecuteCmd(vector argvSv, function DetectFatalLog) +{ + vector argv; + auto getStringViewData = [](const auto &arg) { return arg.data(); }; + transform(argvSv.begin(), argvSv.end(), back_inserter(argv), getStringViewData); + argv.push_back(nullptr); + + // 临时将SIGCHLD恢复成默认值,从而能够从作为僵尸进程的子进程中获得返回值 + BGuardSignal guard(SIGCHLD); + + int pipeFd[2]; + if (pipe(pipeFd) < 0) { + throw BError(BError::Codes::UTILS_INTERRUPTED_PROCESS, generic_category().message(errno)); + } + + pid_t pid = 0; + if ((pid = fork()) == 0) { + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(pipeFd[0]); + UniqueFd fd(pipeFd[1]); + if (dup2(pipeFd[1], STDERR_FILENO) == -1) { + throw BError(BError::Codes::UTILS_INTERRUPTED_PROCESS, generic_category().message(errno)); + } + exit((execvp(argv[0], const_cast(argv.data())) == -1) ? errno : 0); + } + + UniqueFd fd(pipeFd[0]); + close(pipeFd[1]); + if (pid == -1) { + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, generic_category().message(errno)); + } + unique_ptr> pipeStream {fdopen(pipeFd[0], "r"), fclose}; + if (!pipeStream) { + throw BError(errno); + } + fd.Release(); + + return WaitForChild(pid, move(pipeStream), DetectFatalLog); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_cmdline.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_cmdline.cpp new file mode 100644 index 00000000..a5e3da65 --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_cmdline.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_tarball/b_tarball_cmdline.h" + +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_dir.h" +#include "b_process/b_guard_cwd.h" +#include "b_process/b_process.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +static bool IsTarFatalErrorOccur(string_view output) +{ + vector fatalError {"EOF", "bad xform", "bad header", "sparse overflow", + "short header", "empty archive", "Not tar"}; + for (auto &item : fatalError) { + if (output.find(item) != string_view::npos) { + return true; + } + } + return false; +} + +void BTarballCmdline::Tar(string_view root, vector includes, vector excludes) +{ + // 切换到根路径,从而在打包时使用文件或目录的相对路径 + BGuardCwd guard(root); + + vector argv = { + "/system/bin/tar", + "-cf", + tarballPath_, + }; + + if (includes.empty()) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "tar includes argument must be not empty"); + } + + vector includesDirs = BDir::GetDirs(includes); + if (includesDirs.empty()) { + HILOGE("The package path does not exist, and an empty package is generated"); + includesDirs.push_back(""); + } + for (auto &&include : includesDirs) { + argv.push_back(include); + } + vector excludesDirs = BDir::GetDirs(excludes); + for (auto &&exclude : excludesDirs) { + argv.push_back("--exclude"); + argv.push_back(exclude); + } + + // 如果打包后生成了打包文件,则默认打包器打包时生成的错误可以忽略(比如打包一个不存在的文件) + auto [bFatalError, errCode] = BProcess::ExecuteCmd(argv, IsTarFatalErrorOccur); + if (bFatalError || (errCode && access(tarballPath_.data(), F_OK) != 0)) { + stringstream ss; + ss << "Is a fatal error occurred: " << bFatalError << ", error code : " << errCode; + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, ss.str()); + } +} + +void BTarballCmdline::Untar(string_view root) +{ + vector argv = { + "tar", "-xf", tarballPath_, "-C", root, + }; + auto [bFatalError, errCode] = BProcess::ExecuteCmd(argv, IsTarFatalErrorOccur); + if (bFatalError) { + stringstream ss; + ss << "Is a fatal error occurred in untar process: " << bFatalError << ", error code : " << errCode; + throw BError(BError::Codes::UTILS_INVAL_PROCESS_ARG, ss.str()); + } +} + +BTarballCmdline::BTarballCmdline(string_view tarballDir, string_view tarballName) + : tarballDir_(tarballDir), tarballName_(tarballName) +{ + tarballPath_ = tarballDir_ + "/" + tarballName_; +} +} // namespace OHOS::FileManagement::Backup diff --git a/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_factory.cpp b/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_factory.cpp new file mode 100644 index 00000000..ddfedd8a --- /dev/null +++ b/mock/innerkits/filemanagement/app_file_service/utils/src/b_tarball/b_tarball_factory.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_tarball/b_tarball_factory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_tarball/b_tarball_cmdline.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +/** + * @brief Verifying untar input parameters + * + * @param root Root directory for storing unpacked files + * An absolute path is required. + */ +static void UntarFort(string_view root) +{ + auto resolvedPath = make_unique(PATH_MAX); + if (!realpath(root.data(), resolvedPath.get()) || (string_view(resolvedPath.get()) != root)) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "The root must be an existing canonicalized path"); + } +} + +/** + * @brief Filtering tar input parameters + * + * @param tarballDir Directory where the package file is stored + * @param root Root directory of the file to be packed + * An absolute path is required. + * @param includes Path to be packed in the root directory. + * The relative path is required. If this parameter is not specified, all packages are packed by default. + * @param excludes The part that does not need to be packed in the path to be packed + * Requires a relative path. Can be used to exclude some subdirectories + * @return std::tuple, vector> 返回合法的includes, excludes + */ +static tuple, vector> TarFilter(string_view tarballDir, + string_view root, + const vector &includes, + const vector &excludes) +{ + auto resolvedPath = make_unique(PATH_MAX); + if (!realpath(root.data(), resolvedPath.get()) || (string_view(resolvedPath.get()) != root)) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "The root must be an existing canonicalized path"); + } + + auto removeBackSlash = [](const string_view &arg) -> string { + if (arg.empty()) { + return ""; + } + + size_t i = arg.size() - 1; + for (; i > 0; --i) { + if (arg[i] != '/') { + break; + } + } + return {arg.data(), i + 1}; + }; + + vector newExcludes; + for (auto &item : excludes) { + string str = removeBackSlash(item); + if (!str.empty()) { + newExcludes.push_back(str); + } + } + + return {{includes.begin(), includes.end()}, newExcludes}; +} + +/** + * @brief 校验tarball路径,并将之拆分为路径和文件名 + * + * @param tarballPath tarball全路径 + * @return tuple 路径和文件名 + */ +static tuple GetTarballDirAndName(string_view tarballPath) +{ + char *buf4Dir = strdup(tarballPath.data()); + if (!buf4Dir) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "Out of memory"); + } + string tarballDir = dirname(buf4Dir); + free(buf4Dir); + + char *buf4Name = strdup(tarballPath.data()); + if (!buf4Name) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "Out of memory"); + } + string tarballName = basename(buf4Name); + free(buf4Name); + + auto resolvedPath = make_unique(PATH_MAX); + if (!realpath(tarballDir.data(), resolvedPath.get())) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, generic_category().message(errno)); + } + if (auto canonicalizedTarballDir = string_view(resolvedPath.get()); canonicalizedTarballDir != tarballDir) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "Tarball path differed after canonicalizing"); + } + if (auto suffix = string_view(".tar"); + tarballPath.length() <= suffix.length() || + !equal(tarballPath.rbegin(), next(tarballPath.rbegin(), suffix.length()), suffix.rbegin(), suffix.rend())) { + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, "Tarball path didn't end with '.tar'"); + } + return {tarballDir, tarballName}; +} + +/** + * @brief 绑定命令行实现的打包器 + * + * @param tarballDir taball路径 + * @param tarballName taball文件名 + * @return unique_ptr 打包器实现,包括tar和untar两种方法 + * @see GetTarballDirAndName + */ +static unique_ptr BindCmdline(string_view tarballDir, string_view tarballName) +{ + auto ptr = make_shared(tarballDir, tarballName); + + return make_unique(BTarballFactory::Impl { + .tar = bind(&BTarballCmdline::Tar, ptr, placeholders::_1, placeholders::_2, placeholders::_3), + .untar = bind(&BTarballCmdline::Untar, ptr, placeholders::_1), + }); +} + +unique_ptr BTarballFactory::Create(string_view implType, string_view tarballPath) +{ + static map(string_view, string_view)>> mapType2Tarball = { + {"cmdline", BindCmdline}, + }; + + try { + auto [tarballDir, tarballName] = GetTarballDirAndName(tarballPath); + auto tarballImpl = mapType2Tarball.at(implType)(tarballDir, tarballName); + if (tarballImpl->tar) { + tarballImpl->tar = [tarballDir {string(tarballDir)}, tar {tarballImpl->tar}]( + string_view root, vector includes, vector excludes) { + auto [newIncludes, newExcludes] = TarFilter(tarballDir, root, includes, excludes); + tar(root, {newIncludes.begin(), newIncludes.end()}, {newExcludes.begin(), newExcludes.end()}); + }; + } + if (tarballImpl->untar) { + tarballImpl->untar = [untar {tarballImpl->untar}](string_view root) { + UntarFort(root); + untar(root); + }; + } + return tarballImpl; + } catch (const out_of_range &e) { + stringstream ss; + ss << "Unsupported implementation " << implType; + throw BError(BError::Codes::UTILS_INVAL_TARBALL_ARG, ss.str()); + } +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/mock/innerkits/filemanagement/file_api/interfaces/kits/security_label.h b/mock/innerkits/filemanagement/file_api/interfaces/kits/security_label.h new file mode 100644 index 00000000..470a68fe --- /dev/null +++ b/mock/innerkits/filemanagement/file_api/interfaces/kits/security_label.h @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2021-2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef SECURITY_LABEL_H +#define SECURITY_LABEL_H + +#include +#include +#include +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleSecurityLabel { +const char XATTR_KEY[] = {"user.security"}; +const std::string DEFAULT_DATA_LEVEL = "s3"; +const std::set DATA_LEVEL = {"s0", "s1", "s2", "s3", "s4"}; +class SecurityLabel { +public: + static bool SetSecurityLabel(const std::string &path, const std::string &dataLevel) + { + if (DATA_LEVEL.count(dataLevel) != 1) { + return false; + } +#ifdef IOS_PLATFORM + if (setxattr(path.c_str(), XATTR_KEY, dataLevel.c_str(), dataLevel.size(), 0, 0) < 0) { +#else + if (setxattr(path.c_str(), XATTR_KEY, dataLevel.c_str(), dataLevel.size(), 0) < 0) { +#endif + return false; + } + return true; + } + + static std::string GetSecurityLabel(const std::string &path) + { +#ifdef IOS_PLATFORM + auto xattrValueSize = getxattr(path.c_str(), XATTR_KEY, nullptr, 0, 0, 0); +#else + auto xattrValueSize = getxattr(path.c_str(), XATTR_KEY, nullptr, 0); +#endif + if (xattrValueSize == -1 || errno == ENOTSUP) { + return ""; + } + if (xattrValueSize <= 0) { + return DEFAULT_DATA_LEVEL; + } + std::unique_ptr xattrValue = std::make_unique((long)xattrValueSize + 1); + if (xattrValue == nullptr) { + return ""; + } +#ifdef IOS_PLATFORM + xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue.get(), xattrValueSize, 0, 0); +#else + xattrValueSize = getxattr(path.c_str(), XATTR_KEY, xattrValue.get(), xattrValueSize); +#endif + if (xattrValueSize == -1 || errno == ENOTSUP) { + return ""; + } + if (xattrValueSize <= 0) { + return DEFAULT_DATA_LEVEL; + } + return std::string(xattrValue.get()); + } +}; +} // namespace ModuleSecurityLabel +} // namespace FileManagement +} // namespace OHOS +#endif \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/BUILD.gn b/mock/innerkits/netmanager_base/BUILD.gn deleted file mode 100644 index d1b36d30..00000000 --- a/mock/innerkits/netmanager_base/BUILD.gn +++ /dev/null @@ -1,35 +0,0 @@ -import("//build/config/ohos/rules.gni") -import("//build/ohos.gni") - -config("net_conn_manager_if_config") { - include_dirs = [ "net_conn_manager_if/include" ] -} -ohos_prebuilt_shared_library("net_conn_manager_if") { - source = "net_conn_manager_if/libnet_conn_manager_if.z.so" - public_configs = [ ":net_conn_manager_if_config" ] - subsystem_name = "netmanager_base" - part_name = "netmanager_base" - install_enable = false -} - -config("net_policy_manager_if_config") { - include_dirs = [ "net_policy_manager_if/include" ] -} -ohos_prebuilt_shared_library("net_policy_manager_if") { - source = "net_policy_manager_if/libnet_policy_manager_if.z.so" - public_configs = [ ":net_policy_manager_if_config" ] - subsystem_name = "netmanager_base" - part_name = "netmanager_base" - install_enable = false -} - -config("net_stats_manager_if_config") { - include_dirs = [ "net_stats_manager_if/include" ] -} -ohos_prebuilt_shared_library("net_stats_manager_if") { - source = "net_stats_manager_if/libnet_stats_manager_if.z.so" - public_configs = [ ":net_stats_manager_if_config" ] - subsystem_name = "netmanager_base" - part_name = "netmanager_base" - install_enable = false -} diff --git a/mock/innerkits/netmanager_base/innerkits/include/inet_addr.h b/mock/innerkits/netmanager_base/innerkits/include/inet_addr.h new file mode 100644 index 00000000..d24c2cec --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/include/inet_addr.h @@ -0,0 +1,49 @@ +/* + * 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 INET_ADDR_H +#define INET_ADDR_H + +#include + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +struct INetAddr final: public Parcelable { + typedef enum { + UNKNOWN = 0x00, + IPV4 = 0x01, + IPV6 = 0x02, + } IpType; + + uint8_t type_ = UNKNOWN; + uint8_t family_ = 0x00; + uint8_t prefixlen_ = 0; + std::string address_; + std::string netMask_; + std::string hostName_; + uint8_t port_ = 0; + + bool operator==(const INetAddr& obj) const; + + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(Parcel &parcel); + static bool Marshalling(Parcel &parcel, const sptr &object); + std::string ToString(const std::string &tab) const; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/include/net_manager_constants.h b/mock/innerkits/netmanager_base/innerkits/include/net_manager_constants.h new file mode 100644 index 00000000..2914c15e --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/include/net_manager_constants.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETMANAGER_CONSTANTS_H +#define NETMANAGER_CONSTANTS_H + +#include "errors.h" + +namespace OHOS { +namespace NetManagerStandard { +constexpr int NETMANAGER_ERROR = -1; +constexpr int NETSYS_SUCCESS = 0; + +enum { + NETMANAGER_COMMON = 0x00, + NETMANAGER_DNS_RESOLVER_MANAGER = 0x01, + NETMANAGER_NET_CONN_MANAGER = 0x03, + NETMANAGER_NET_POLICY_MANAGER = 0x04, +}; + +// Error code for common +constexpr ErrCode COMMON_ERR_OFFSET = ErrCodeOffset(SUBSYS_COMMUNICATION, NETMANAGER_COMMON); + +enum { + NETMANAGER_ERR_PERMISSION_DENIED = 201, + NETMANAGER_ERR_NOT_SYSTEM_CALL = 202, + NETMANAGER_ERR_PARAMETER_ERROR = 401, + NETMANAGER_ERR_CAPABILITY_NOT_SUPPORTED = 801, + NETMANAGER_SUCCESS = 0, + NETMANAGER_ERR_INVALID_PARAMETER = 2100001, + NETMANAGER_ERR_OPERATION_FAILED = 2100002, + NETMANAGER_ERR_INTERNAL = 2100003, + NETMANAGER_ERR_MEMCPY_FAIL = 2100101, + NETMANAGER_ERR_MEMSET_FAIL = 2100102, + NETMANAGER_ERR_STRCPY_FAIL = 2100103, + NETMANAGER_ERR_STRING_EMPTY = 2100104, + NETMANAGER_ERR_LOCAL_PTR_NULL = 2100105, + NETMANAGER_ERR_DESCRIPTOR_MISMATCH = 2100201, + NETMANAGER_ERR_WRITE_DESCRIPTOR_TOKEN_FAIL = 2100202, + NETMANAGER_ERR_WRITE_DATA_FAIL = 2100203, + NETMANAGER_ERR_WRITE_REPLY_FAIL = 2100204, + NETMANAGER_ERR_READ_DATA_FAIL = 2100205, + NETMANAGER_ERR_READ_REPLY_FAIL = 2100206, + NETMANAGER_ERR_IPC_CONNECT_STUB_FAIL = 2100207, + NETMANAGER_ERR_GET_PROXY_FAIL = 2100208, +}; + +enum { + NETMANAGER_EXT_ERR_PERMISSION_DENIED = 201, + NETMANAGER_EXT_ERR_NOT_SYSTEM_CALL = 202, + NETMANAGER_EXT_ERR_PARAMETER_ERROR = 401, + NETMANAGER_EXT_ERR_CAPABILITY_NOT_SUPPORTED = 801, + NETMANAGER_EXT_SUCCESS = 0, + NETMANAGER_EXT_ERR_INVALID_PARAMETER = 2200001, + NETMANAGER_EXT_ERR_OPERATION_FAILED = 2200002, + NETMANAGER_EXT_ERR_INTERNAL = 2200003, + NETMANAGER_EXT_ERR_MEMCPY_FAIL = 2200101, + NETMANAGER_EXT_ERR_MEMSET_FAIL = 2200102, + NETMANAGER_EXT_ERR_STRCPY_FAIL = 2200103, + NETMANAGER_EXT_ERR_STRING_EMPTY = 2200104, + NETMANAGER_EXT_ERR_LOCAL_PTR_NULL = 2200105, + NETMANAGER_EXT_ERR_DESCRIPTOR_MISMATCH = 2200201, + NETMANAGER_EXT_ERR_WRITE_DESCRIPTOR_TOKEN_FAIL = 2200202, + NETMANAGER_EXT_ERR_WRITE_DATA_FAIL = 2200203, + NETMANAGER_EXT_ERR_WRITE_REPLY_FAIL = 2200204, + NETMANAGER_EXT_ERR_READ_DATA_FAIL = 2200205, + NETMANAGER_EXT_ERR_READ_REPLY_FAIL = 2200206, + NETMANAGER_EXT_ERR_IPC_CONNECT_STUB_FAIL = 2200207, + NETMANAGER_EXT_ERR_GET_PROXY_FAIL = 2200208, +}; + +enum { + ETHERNET_ERR_INIT_FAIL = 2201001, + ETHERNET_ERR_EMPTY_CONFIGURATION = 2201002, + ETHERNET_ERR_DUMP = 2201003, + ETHERNET_ERR_DEVICE_CONFIGURATION_INVALID = 2201004, + ETHERNET_ERR_DEVICE_INFORMATION_NOT_EXIST = 2201005, + ETHERNET_ERR_DEVICE_NOT_LINK = 2201006, + ETHERNET_ERR_USER_CONIFGURATION_WRITE_FAIL = 2201007, + ETHERNET_ERR_USER_CONIFGURATION_CLEAR_FAIL = 2201008, + ETHERNET_ERR_CONVERT_CONFIGURATINO_FAIL = 2201009 +}; + +enum { + NETWORKSHARE_ERROR_UNKNOWN_TYPE = 2202002, + NETWORKSHARE_ERROR_UNKNOWN_IFACE = 2202003, + NETWORKSHARE_ERROR_UNAVAIL_IFACE = 2202004, + NETWORKSHARE_ERROR_WIFI_SHARING = 2202005, + NETWORKSHARE_ERROR_BT_SHARING = 2202006, + NETWORKSHARE_ERROR_USB_SHARING = 2202007, + NETWORKSHARE_ERROR_SHARING_IFACE_ERROR = 2202008, + NETWORKSHARE_ERROR_ENABLE_FORWARDING_ERROR = 2202009, + NETWORKSHARE_ERROR_INTERNAL_ERROR = 2202010, + NETWORKSHARE_ERROR_IFACE_CFG_ERROR = 2202011, + NETWORKSHARE_ERROR_DHCPSERVER_ERROR = 2202012, + NETWORKSHARE_ERROR_ISSHARING_CALLBACK_ERROR = 2202013, +}; + +enum { + NETWORKVPN_ERROR_REFUSE_CREATE_VPN = 2203001, + NETWORKVPN_ERROR_VPN_EXIST = 2203002, + NETWORKVPN_ERROR_INVALID_FD = 2203004, +}; + +enum { + NET_MDNS_ERR_UNKNOWN = 2204001, + NET_MDNS_ERR_CALLBACK_NOT_FOUND = 2204002, + NET_MDNS_ERR_CALLBACK_DUPLICATED = 2204003, + NET_MDNS_ERR_PAYLOAD_PARSER_FAIL = 2204004, + NET_MDNS_ERR_EMPTY_PAYLOAD = 2204005, + NET_MDNS_ERR_TIMEOUT = 2204006, + NET_MDNS_ERR_ILLEGAL_ARGUMENT = NETMANAGER_ERR_PARAMETER_ERROR, + NET_MDNS_ERR_SERVICE_INSTANCE_DUPLICATE = 2204007, + NET_MDNS_ERR_SERVICE_INSTANCE_NOT_FOUND = 2204008, + NET_MDNS_ERR_SEND = 2204009, + NET_MDNS_ERR_WRITE_DUMP = 2204010, +}; + +// Error code for netmanager dns resolver +constexpr ErrCode DNS_ERR_OFFSET = ErrCodeOffset(SUBSYS_COMMUNICATION, NETMANAGER_DNS_RESOLVER_MANAGER); +// Error code for netmanager conn manager +constexpr ErrCode CONN_MANAGER_ERR_OFFSET = ErrCodeOffset(SUBSYS_COMMUNICATION, NETMANAGER_NET_CONN_MANAGER); +// Error code for netmanager policy manager +constexpr ErrCode POLICY_MANAGER_ERR_OFFSET = ErrCodeOffset(SUBSYS_COMMUNICATION, NETMANAGER_NET_POLICY_MANAGER); +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NETMANAGER_CONSTANTS_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/BUILD.gn b/mock/innerkits/netmanager_base/innerkits/netconnclient/BUILD.gn new file mode 100644 index 00000000..a96de5e0 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/BUILD.gn @@ -0,0 +1,143 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/netmanager_base/netmanager_base_config.gni") + +config("net_conn_manager_if_config") { + # header file path + include_dirs = [ + "$INNERKITS_ROOT/netconnclient/include", + "$INNERKITS_ROOT/netconnclient/include/proxy", + "$INNERKITS_ROOT/include", + ] + + cflags = [] + if (is_double_framework) { + cflags += [ "-DCONFIG_DUAL_FRAMEWORK" ] + } + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + if (is_standard_system) { + cflags += [ "-DCONFIG_STANDARD_SYSTEM" ] + } + if (defined(build_public_version) && build_public_version) { + cflags += [ "-DBUILD_PUBLIC_VERSION" ] + } +} + +ohos_source_set("net_conn_parcel") { + sources = [ + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/http_proxy.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/inet_addr.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_all_capabilities.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_interface_config.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_link_info.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_specifier.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_supplier_info.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/route.cpp", + ] + + include_dirs = [ + "$INNERKITS_ROOT/include", + "$INNERKITS_ROOT/netconnclient/include", + "$INNERKITS_ROOT/netmanagernative/include", + "$NETSYSNATIVE_SOURCE_DIR/include/netsys", + ] + + deps = [ "$NETMANAGER_BASE_ROOT/utils:net_manager_common" ] + + external_deps = [ "c_utils:utils" ] + external_deps += [ "hilog:libhilog" ] + + part_name = "netmanager_base" + subsystem_name = "communication" +} + +ohos_shared_library("net_conn_manager_if") { + sanitize = { + cfi = true + integer_overflow = true + boundary_sanitize = true + all_ubsan = true + blocklist = "./connect_blocklist.txt" + } + + sources = [ + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_conn_client.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_handle.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/net_supplier_callback_base.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_conn_callback_stub.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_conn_service_proxy.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_detection_callback_stub.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_interface_callback_stub.cpp", + "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_supplier_callback_stub.cpp", + ] + + include_dirs = [ + "$INNERKITS_ROOT/netmanagernative/include", + "$NETMANAGERNATIVE_ROOT/fwmarkclient/include", + "$NETMANAGER_BASE_ROOT/utils/log/include", + "//third_party/musl/porting/linux/user/src/hook", + ] + + version_script = "libnetconn_kits.map" + + public_configs = [ ":net_conn_manager_if_config" ] + + deps = [ + ":net_conn_parcel", + "$NETMANAGER_BASE_ROOT/services/netmanagernative/fwmarkclient:fwmark_client", + ] + + external_deps = [ + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + + defines = [ + "NETMGR_LOG_TAG = \"NetConnManager\"", + "LOG_DOMAIN = 0xD0015B0", + ] + + if (enable_netmgr_debug) { + defines += [ "NETMGR_DEBUG" ] + } + + external_deps += [ "hilog:libhilog" ] + + innerapi_tags = [ "platformsdk" ] + part_name = "netmanager_base" + subsystem_name = "communication" +} + +config("socket_permission_config") { + include_dirs = [ "$INNERKITS_ROOT/netconnclient/include" ] +} + +ohos_shared_library("socket_permission") { + sanitize = { + cfi = true + cfi_cross_dso = true + integer_overflow = true + boundary_sanitize = true + all_ubsan = true + } + + sources = [ "$NETCONNMANAGER_INNERKITS_SOURCE_DIR/src/socket_permission.cpp" ] + deps = [ "$INNERKITS_ROOT/netconnclient:net_conn_manager_if" ] + public_configs = [ ":socket_permission_config" ] + part_name = "netmanager_base" + subsystem_name = "communication" +} diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/connect_blocklist.txt b/mock/innerkits/netmanager_base/innerkits/netconnclient/connect_blocklist.txt new file mode 100644 index 00000000..229824e1 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/connect_blocklist.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[cfi] +type:*OHOS::Parcel* +type:*OHOS::RefBase* +fun:*Marshalling* +src:*net_conn_service_proxy.cpp \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/http_proxy.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/http_proxy.h new file mode 100644 index 00000000..1bfec488 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/http_proxy.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETMANAGER_BASE_HTTP_PROXY_H +#define NETMANAGER_BASE_HTTP_PROXY_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +class HttpProxy final: public Parcelable { +public: + HttpProxy(); + HttpProxy(std::string host, uint16_t port, const std::list &exclusionList); + + [[nodiscard]] std::string GetHost() const; + [[nodiscard]] uint16_t GetPort() const; + [[nodiscard]] std::list GetExclusionList() const; + [[nodiscard]] std::string ToString() const; + void inline SetHost(std::string &&host) + { + host_ = host; + } + void inline SetPort(uint16_t port) + { + port_ = port; + } + void inline SetExclusionList(const std::list &list) + { + exclusionList_ = list; + } + + bool operator==(const HttpProxy &httpProxy) const; + bool operator!=(const HttpProxy &httpProxy) const; + bool Marshalling(Parcel &parcel) const override; + static bool Unmarshalling(Parcel &parcel, HttpProxy &httpProxy); + +private: + std::string host_; + uint16_t port_; + std::list exclusionList_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif /* NETMANAGER_BASE_HTTP_PROXY_H */ diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_all_capabilities.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_all_capabilities.h new file mode 100644 index 00000000..03c6b602 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_all_capabilities.h @@ -0,0 +1,67 @@ +/* + * 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 NET_ALL_CAPABILITIES_H +#define NET_ALL_CAPABILITIES_H + +#include + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +enum NetCap { + NET_CAPABILITY_MMS = 0, + NET_CAPABILITY_NOT_METERED = 11, + NET_CAPABILITY_INTERNET = 12, + NET_CAPABILITY_NOT_VPN = 15, + NET_CAPABILITY_VALIDATED = 16, + NET_CAPABILITY_CAPTIVE_PORTAL = 17, + NET_CAPABILITY_INTERNAL_DEFAULT +}; + +enum NetBearType { + BEARER_CELLULAR = 0, + BEARER_WIFI = 1, + BEARER_BLUETOOTH = 2, + BEARER_ETHERNET = 3, + BEARER_VPN = 4, + BEARER_WIFI_AWARE = 5, + BEARER_DEFAULT +}; + +struct NetAllCapabilities final: public Parcelable { + uint32_t linkUpBandwidthKbps_ = 0; + uint32_t linkDownBandwidthKbps_ = 0; + std::set netCaps_; + std::set bearerTypes_; + + NetAllCapabilities() = default; + NetAllCapabilities(const NetAllCapabilities &cap); + NetAllCapabilities &operator=(const NetAllCapabilities &cap); + + bool CapsIsValid() const; + bool CapsIsNull() const; + bool Marshalling(Parcel &parcel) const override; + bool Unmarshalling(Parcel &parcel); + std::string ToString(const std::string &tab) const; + +private: + void ToStrNetCaps(const std::set &netCaps, std::string &str) const; + void ToStrNetBearTypes(const std::set &bearerTypes, std::string &str) const; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_ALL_CAPABILITIES_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_client.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_client.h new file mode 100644 index 00000000..2e1ccb73 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_client.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_CONN_MANAGER_H +#define NET_CONN_MANAGER_H + +#include +#include + +#include "parcel.h" +#include "singleton.h" + +#include "http_proxy.h" +#include "i_net_conn_service.h" +#include "i_net_interface_callback.h" +#include "i_net_supplier_callback.h" +#include "net_handle.h" +#include "net_link_info.h" +#include "net_specifier.h" +#include "net_supplier_callback_base.h" + +namespace OHOS { +namespace nmd { +class FwmarkClient; +} +namespace NetManagerStandard { +class NetConnClient { +public: + static NetConnClient &GetInstance(); + + /** + * The interface in NetConnService can be called when the system is ready + * + * @return Returns 0, the system is ready, otherwise the system is not ready + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SystemReady(); + + /** + * The interface is set permission for network + * + * @param The specified UID of app + * @param allow internet permission + * @return Returns 0, unregister the network successfully, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SetInternetPermission(uint32_t uid, uint8_t allow); + + /** + * The interface is register the network + * + * @param bearerType Bearer Network Type + * @param ident Unique identification of mobile phone card + * @param netCaps Network capabilities registered by the network supplier + * @param supplierId out param, return supplier id + * @return Returns 0, unregister the network successfully, otherwise it will fail + */ + int32_t RegisterNetSupplier(NetBearType bearerType, const std::string &ident, const std::set &netCaps, + uint32_t &supplierId); + + /** + * The interface is unregister the network + * + * @param supplierId The id of the network supplier + * @return Returns 0, unregister the network successfully, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UnregisterNetSupplier(uint32_t supplierId); + + /** + * Register supplier callback + * + * @param supplierId The id of the network supplier + * @param callback INetSupplierCallback callback interface + * @return Returns 0, unregister the network successfully, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t RegisterNetSupplierCallback(uint32_t supplierId, const sptr &callback); + + /** + * The interface is update network connection status information + * + * @param supplierId The id of the network supplier + * @param netSupplierInfo network connection status information + * @return Returns 0, successfully update the network connection status information, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UpdateNetSupplierInfo(uint32_t supplierId, const sptr &netSupplierInfo); + + /** + * The interface is update network link attribute information + * + * @param supplierId The id of the network supplier + * @param netLinkInfo network link attribute information + * @return Returns 0, successfully update the network link attribute information, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UpdateNetLinkInfo(uint32_t supplierId, const sptr &netLinkInfo); + + /** + * Register net connection callback + * + * @param callback The callback of INetConnCallback interface + * @return Returns 0, successfully register net connection callback, otherwise it will failed + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t RegisterNetConnCallback(const sptr &callback); + + /** + * Register net connection callback by NetSpecifier + * + * @param netSpecifier specifier information + * @param callback The callback of INetConnCallback interface + * @param timeoutMS net connection time out + * @return Returns 0, successfully register net connection callback, otherwise it will failed + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t RegisterNetConnCallback(const sptr &netSpecifier, const sptr &callback, + const uint32_t &timeoutMS); + + /** + * Unregister net connection callback + * + * @param callback The callback of INetConnCallback interface + * @return Returns 0, successfully unregister net connection callback, otherwise it will fail + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UnregisterNetConnCallback(const sptr &callback); + + /** + * The interface is to get default network + * + * @param netHandle network handle + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetDefaultNet(NetHandle &netHandle); + + /** + * The interface is to check whether has default network + * + * @param flag has default network or not + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t HasDefaultNet(bool &flag); + + /** + * The interface is to get all acvite network + * + * @param netList a list of network + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAllNets(std::list> &netList); + + /** + * get the network link information of the connection + * + * @param netHandle network handle + * @param info network link infomation + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetConnectionProperties(const NetHandle &netHandle, NetLinkInfo &info); + + /** + * get all capabilities from network + * + * @param netHandle network handle + * @param netAllCap network all of capabilities + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetNetCapabilities(const NetHandle &netHandle, NetAllCapabilities &netAllCap); + + /** + * The interface is to get addresses by network name + * + * @param host domain name + * @param netId network id + * @param addrList list of network addresses + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAddressesByName(const std::string &host, int32_t netId, std::vector &addrList); + + /** + * The interface is to get address by network name + * + * @param host domain name + * @param netId network + * @param addr network address + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAddressByName(const std::string &host, int32_t netId, INetAddr &addr); + + /** + * The interface is to bind socket + * + * @param socket_fd socket file description + * @param netId network id + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t BindSocket(int32_t socket_fd, int32_t netId); + + /** + * The interface of network detection called by the application + * + * @param netHandle network handle + * @return int32_t Whether the network probe is successful + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t NetDetection(const NetHandle &netHandle); + + /** + * set air plane mode on or off + * + * @param state air plane mode on or not + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SetAirplaneMode(bool state); + + /** + * check whether the network meter is default + * + * @param isMetered the network meter is default or not + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t IsDefaultNetMetered(bool &isMetered); + + /** + * set global http proxy in the network + * + * @param httpProxy http proxy + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SetGlobalHttpProxy(const HttpProxy &httpProxy); + + /** + * get global http proxy in the network + * + * @param httpProxy http proxy + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetGlobalHttpProxy(HttpProxy &httpProxy); + + /** + * set network id of app binding network + * + * @param netId network id + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetDefaultHttpProxy(HttpProxy &httpProxy); + + /** + * set network id of app binding network + * + * @param netId network id + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SetAppNet(int32_t netId); + + /** + * get network id of app binding network + * + * @param netId network id + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAppNet(int32_t &netId); + + /** + * Get network id by identifier + * + * @param ident identifier + * @param netIdList list of network id + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetNetIdByIdentifier(const std::string &ident, std::list &netIdList); + + /** + * Register network interface state change callback + * + * @param callback The callback of INetInterfaceStateCallback interface + * @return Returns 0, successfully register net connection callback, otherwise it will failed + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t RegisterNetInterfaceCallback(const sptr &callback); + + /** + * Get network interface configuration + * + * @param ifaceName Network port device name + * @param config Network interface configuration + * @return Returns 0, successfully register net connection callback, otherwise it will failed + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetNetInterfaceConfiguration(const std::string &iface, NetInterfaceConfiguration &config); + +private: + class NetConnDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit NetConnDeathRecipient(NetConnClient &client) : client_(client) {} + ~NetConnDeathRecipient() override = default; + void OnRemoteDied(const wptr &remote) override + { + client_.OnRemoteDied(remote); + } + + private: + NetConnClient &client_; + }; + +private: + NetConnClient(); + ~NetConnClient(); + NetConnClient& operator=(const NetConnClient&) = delete; + NetConnClient(const NetConnClient&) = delete; + + sptr GetProxy(); + void OnRemoteDied(const wptr &remote); + +private: + std::mutex mutex_; + sptr NetConnService_; + sptr deathRecipient_; + std::map> netSupplierCallback_; +}; +} // namespace NetManagerStandard +} // namespace OHOS + +#endif // NET_CONN_MANAGER_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_constants.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_constants.h new file mode 100644 index 00000000..e46c736a --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_conn_constants.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef NET_CONN_CONSTANTS_H +#define NET_CONN_CONSTANTS_H + +#include "net_manager_constants.h" + +namespace OHOS { +namespace NetManagerStandard { +enum NetConnResultCode { + NET_CONN_ERR_INVALID_SUPPLIER_ID = 2101002, + NET_CONN_ERR_NET_TYPE_NOT_FOUND = 2101003, + NET_CONN_ERR_NO_ANY_NET_TYPE = 2101004, + NET_CONN_ERR_NO_REGISTERED = 2101005, + NET_CONN_ERR_NETID_NOT_FOUND = 2101006, + NET_CONN_ERR_CALLBACK_NOT_FOUND = 2101007, + NET_CONN_ERR_SAME_CALLBACK = 2101008, + NET_CONN_ERR_REQ_ID_NOT_FOUND = 2101009, + NET_CONN_ERR_NO_DEFAULT_NET = 2101010, + NET_CONN_ERR_HTTP_PROXY_INVALID = 2101011, + NET_CONN_ERR_NO_HTTP_PROXY = 2101012, + NET_CONN_ERR_INVALID_NETWORK = 2101013, + NET_CONN_ERR_SERVICE_REQUEST_CONNECT_FAIL = 2101014, + NET_CONN_ERR_SERVICE_UPDATE_NET_LINK_INFO_FAIL = 2101015, + NET_CONN_ERR_NO_SUPPLIER = 2101016, + NET_CONN_ERR_NET_MONITOR_OPT_FAILED = 2101017, + NET_CONN_ERR_SERVICE_NO_REQUEST = 2101018, + NET_CONN_ERR_NO_ADDRESS = 2101019, + NET_CONN_ERR_NET_NOT_FIND_BESTNETWORK_FOR_REQUEST = 2101020, + NET_CONN_ERR_NET_NO_RESTRICT_BACKGROUND = 2101021, + NET_CONN_ERR_NET_OVER_MAX_REQUEST_NUM = 2101022, + NET_CONN_ERR_CREATE_DUMP_FAILED = 2101023, + NET_CONN_SUCCESS = NETMANAGER_SUCCESS, + NET_CONN_ERR_INPUT_NULL_PTR = -2, +}; + +enum NetDetectionResultCode { + NET_DETECTION_FAIL = 0, + NET_DETECTION_SUCCESS, + NET_DETECTION_CAPTIVE_PORTAL, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_CONN_CONSTANTS_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_client.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_handle.h similarity index 34% rename from mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_client.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_handle.h index d1306aff..7a6e7e6a 100644 --- a/mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_client.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_handle.h @@ -13,58 +13,42 @@ * limitations under the License. */ -#ifndef NET_STATS_MANAGER_H -#define NET_STATS_MANAGER_H +#ifndef NET_HANDLE_H +#define NET_HANDLE_H #include +#include #include "parcel.h" #include "singleton.h" -#include "i_net_stats_service.h" -#include "net_stats_constants.h" -#include "net_stats_info.h" +#include "inet_addr.h" namespace OHOS { namespace NetManagerStandard { -class NetStatsClient { - DECLARE_DELAYED_SINGLETON(NetStatsClient) - +class NetHandle : public virtual RefBase { public: - int32_t RegisterNetStatsCallback(const sptr &callback); - int32_t UnregisterNetStatsCallback(const sptr &callback); - NetStatsResultCode GetIfaceStatsDetail(const std::string &iface, uint32_t start, uint32_t end, - NetStatsInfo &statsInfo); - NetStatsResultCode GetUidStatsDetail(const std::string &iface, uint32_t uid, - uint32_t start, uint32_t end, NetStatsInfo &statsInfo); - NetStatsResultCode UpdateIfacesStats(const std::string &iface, - uint32_t start, uint32_t end, const NetStatsInfo &stats); - NetStatsResultCode UpdateStatsData(); - NetStatsResultCode ResetFactory(); + NetHandle() : netId_(0) {} + explicit NetHandle(int32_t netId) : netId_(netId) {} + ~NetHandle() override = default; -private: - class NetStatsDeathRecipient : public IRemoteObject::DeathRecipient { - public: - explicit NetStatsDeathRecipient(NetStatsClient &client) : client_(client) {} - ~NetStatsDeathRecipient() override = default; - void OnRemoteDied(const wptr &remote) override - { - client_.OnRemoteDied(remote); - } + int32_t BindSocket(int32_t socket_fd); + int32_t GetAddressesByName(const std::string &host, std::vector &addrList); + int32_t GetAddressByName(const std::string &host, INetAddr &addr); - private: - NetStatsClient &client_; - }; + void SetNetId(int32_t netId) + { + netId_ = netId; + } -private: - sptr GetProxy(); - void OnRemoteDied(const wptr &remote); + int32_t GetNetId() const + { + return netId_; + } private: - std::mutex mutex_; - sptr netStatsService_; - sptr deathRecipient_; + int32_t netId_; }; } // namespace NetManagerStandard } // namespace OHOS -#endif // NET_STATS_MANAGER_H \ No newline at end of file +#endif // NET_HANDLE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_interface_config.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_interface_config.h new file mode 100644 index 00000000..ce6b2a9e --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_interface_config.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_INTERFACE_CONFIG_H +#define NET_INTERFACE_CONFIG_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +struct NetInterfaceConfiguration : public Parcelable { + std::string ifName_; + std::string hwAddr_; + std::string ipv4Addr_; + int prefixLength_ = 0; + std::vector flags_; + + bool IsInterfaceUp(); + bool IsInterfaceRunning(); + + bool Marshalling(Parcel &parcel) const override; + static bool Unmarshalling(Parcel &parcel, NetInterfaceConfiguration &config); +}; +} // namespace nmd +} // namespace OHOS +#endif // NET_INTERFACE_CONFIG_H diff --git a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_link_info.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_link_info.h similarity index 80% rename from mock/innerkits/netmanager_base/net_conn_manager_if/include/net_link_info.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_link_info.h index 41fb947a..310fa789 100644 --- a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_link_info.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_link_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,13 +18,14 @@ #include +#include "http_proxy.h" #include "inet_addr.h" #include "net_specifier.h" #include "route.h" namespace OHOS { namespace NetManagerStandard { -struct NetLinkInfo : public Parcelable { +struct NetLinkInfo final: public Parcelable { std::string ifaceName_; std::string domain_; std::list netAddrList_; @@ -32,17 +33,21 @@ struct NetLinkInfo : public Parcelable { std::list routeList_; uint16_t mtu_ = 0; std::string tcpBufferSizes_; + HttpProxy httpProxy_; - virtual bool Marshalling(Parcel &parcel) const override; + NetLinkInfo() = default; + NetLinkInfo(const NetLinkInfo &cap); + NetLinkInfo &operator=(const NetLinkInfo &cap); + + bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &parcel); static bool Marshalling(Parcel &parcel, const sptr &object); void Initialize(); std::string ToString(const std::string &tab) const; - std::string ToStringBase(const std::string &tab) const; std::string ToStringAddr(const std::string &tab) const; std::string ToStringDns(const std::string &tab) const; std::string ToStringRoute(const std::string &tab) const; }; } // namespace NetManagerStandard } // namespace OHOS -#endif // NET_LINK_INFO_H \ No newline at end of file +#endif // NET_LINK_INFO_H diff --git a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_specifier.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_specifier.h similarity index 91% rename from mock/innerkits/netmanager_base/net_conn_manager_if/include/net_specifier.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_specifier.h index 43354f60..c3e9d8e3 100644 --- a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_specifier.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_specifier.h @@ -24,7 +24,7 @@ namespace OHOS { namespace NetManagerStandard { -struct NetSpecifier : public Parcelable { +struct NetSpecifier final: public Parcelable { std::string ident_; NetAllCapabilities netCapabilities_; @@ -34,7 +34,7 @@ struct NetSpecifier : public Parcelable { void SetTypes(const std::set &bearerTypes); void SetType(NetBearType bearerType); - virtual bool Marshalling(Parcel &parcel) const override; + bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &parcel); static bool Marshalling(Parcel &parcel, const sptr &object); std::string ToString(const std::string &tab) const; diff --git a/mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_info.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_callback_base.h similarity index 55% rename from mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_info.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_callback_base.h index a060ff97..392a6a59 100644 --- a/mock/innerkits/netmanager_base/net_stats_manager_if/include/net_stats_info.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_callback_base.h @@ -13,24 +13,25 @@ * limitations under the License. */ -#ifndef NET_STATS_INFO_H -#define NET_STATS_INFO_H +#ifndef NET_SUPPLIER_CALLBACK_BASE_H +#define NET_SUPPLIER_CALLBACK_BASE_H -#include "parcel.h" -#include "net_stats_constants.h" +#include +#include + +#include "refbase.h" + +#include "net_all_capabilities.h" namespace OHOS { namespace NetManagerStandard { -struct NetStatsInfo : public Parcelable { - int64_t rxBytes_ = 0; - int64_t txBytes_ = 0; - int64_t rxPackets_ = 0; - int64_t txPackets_ = 0; +class NetSupplierCallbackBase : public virtual RefBase { +public: + virtual ~NetSupplierCallbackBase() = default; - virtual bool Marshalling(Parcel &parcel) const override; - static bool Marshalling(Parcel &parcel, const NetStatsInfo &stats); - static bool Unmarshalling(Parcel &parcel, NetStatsInfo &stats); + virtual int32_t RequestNetwork(const std::string &ident, const std::set &netCaps); + virtual int32_t ReleaseNetwork(const std::string &ident, const std::set &netCaps); }; -} // namespace NetManagerStandard -} // namespace OHOS -#endif // NET_STATS_INFO_H +} // NetManagerStandard +} // OHOS +#endif // NET_SUPPLIER_CALLBACK_BASE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_supplier_info.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_info.h similarity index 91% rename from mock/innerkits/netmanager_base/net_conn_manager_if/include/net_supplier_info.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_info.h index 42750787..c7ec8915 100644 --- a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_supplier_info.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/net_supplier_info.h @@ -30,7 +30,7 @@ enum NetConnState { NET_CONN_STATE_DISCONNECTING = 4, NET_CONN_STATE_DISCONNECTED = 5, }; -struct NetSupplierInfo : public Parcelable { +struct NetSupplierInfo final: public Parcelable { bool isAvailable_ = false; bool isRoaming_ = false; int8_t strength_ = 0x00; @@ -39,7 +39,7 @@ struct NetSupplierInfo : public Parcelable { uint32_t linkDownBandwidthKbps_ = 0; int32_t uid_ = 0; - virtual bool Marshalling(Parcel &parcel) const override; + bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &parcel); static bool Marshalling(Parcel &parcel, const sptr &object); std::string ToString(const std::string &tab) const; diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/conn_ipc_interface_code.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/conn_ipc_interface_code.h new file mode 100644 index 00000000..7bc53b4d --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/conn_ipc_interface_code.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONN_IPC_INTERFACE_CODE_H +#define CONN_IPC_INTERFACE_CODE_H + +/* SAID: 1151 */ +namespace OHOS { +namespace NetManagerStandard { +enum class ConnInterfaceCode { + CMD_NM_START, + CMD_NM_REGISTER_NET_SUPPLIER, + CMD_NM_SYSTEM_READY, + CMD_NM_REGISTER_NET_CONN_CALLBACK, + CMD_NM_REGISTER_NET_CONN_CALLBACK_BY_SPECIFIER, + CMD_NM_UNREGISTER_NET_CONN_CALLBACK, + CMD_NM_REG_NET_SUPPLIER, + CMD_NM_UNREG_NETWORK, + CMD_NM_SET_NET_SUPPLIER_INFO, + CMD_NM_SET_NET_LINK_INFO, + CMD_NM_GETDEFAULTNETWORK, + CMD_NM_HASDEFAULTNET, + CMD_NM_NET_DETECTION, + CMD_NM_GET_IFACE_NAMES, + CMD_NM_GET_IFACENAME_BY_TYPE, + CMD_NM_GET_ADDRESSES_BY_NAME, + CMD_NM_GET_ADDRESS_BY_NAME, + CMD_NM_GET_SPECIFIC_NET, + CMD_NM_GET_ALL_NETS, + CMD_NM_GET_SPECIFIC_UID_NET, + CMD_NM_GET_CONNECTION_PROPERTIES, + CMD_NM_GET_NET_CAPABILITIES, + CMD_NM_BIND_SOCKET, + CMD_NM_REGISTER_NET_DETECTION_RET_CALLBACK, + CMD_NM_UNREGISTER_NET_DETECTION_RET_CALLBACK, + CMD_NM_UPDATE_NET_STATE_FOR_TEST, + CMD_NM_REGISTER_NET_SUPPLIER_CALLBACK, + CMD_NM_SET_AIRPLANE_MODE, + CMD_NM_IS_DEFAULT_NET_METERED, + CMD_NM_SET_GLOBAL_HTTP_PROXY, + CMD_NM_GET_GLOBAL_HTTP_PROXY, + CMD_NM_GET_NET_ID_BY_IDENTIFIER, + CMD_NM_SET_APP_NET, + CMD_NM_SET_INTERNET_PERMISSION, + CMD_NM_GET_DEFAULT_HTTP_PROXY, + CMD_NM_REGISTER_NET_INTERFACE_CALLBACK, + CMD_NM_GET_INTERFACE_CONFIGURATION, + CMD_NM_END, +}; + +enum class AdjCallbackInterfaceCode { + ADJ_ADD, + ADJ_REMOVE, +}; + +enum class AdjServiceInterfaceCode { + CMD_NM_ADJ_SYSTEM_READY, + CMD_NM_ADJ_ADD_IFACE, + CMD_NM_ADJ_REMOVE_ADJ_IFACE, + CMD_NM_ADJ_REGISTER_ADJ_CALLBACK, + CMD_NM_ADJ_UNREGISTER_ADJ_CALLBACK, + CMD_NM_ADJ_UPDATE_ADJ_INFO, + CMD_NM_ADJ_END, +}; + +enum class ConnCallbackInterfaceCode { + NET_AVAILABLE, + NET_CAPABILITIES_CHANGE, + NET_CONNECTION_PROPERTIES_CHANGE, + NET_LOST, + NET_UNAVAILABLE, + NET_BLOCK_STATUS_CHANGE, +}; + +enum class DetectionCallback { + NET_DETECTION_RESULT = 0, +}; + +enum class InterfaceCallbackInterfaceCode { + CMD_ON_IFACE_ADDR_UPDATED, + CMD_ON_IFACE_ADDR_REMOVED, + CMD_ON_IFACE_ADDED, + CMD_ON_IFACE_REMOVED, + CMD_ON_IFACE_CHANGED, + CMD_ON_IFACE_LINK_STATE_CHANGED, +}; + +enum class SupplierInterfaceCode { + NET_SUPPLIER_REQUEST_NETWORK = 0, + NET_SUPPLIER_RELEASE_NETWORK = 1, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // CONN_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_callback.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_callback.h new file mode 100644 index 00000000..9fc22c9c --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_callback.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef COMMUNICATION_I_NET_ADJ_CALLBACK_H +#define COMMUNICATION_I_NET_ADJ_CALLBACK_H + +#include "iremote_broker.h" + +#include "net_adj_info.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetAdjCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetAdjCallback"); + ~INetAdjCallback() override = default; + + virtual int32_t NetAdjAdd(const sptr &adjInfo) = 0; + virtual int32_t NetAdjRemove(const sptr &adjInfo) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // COMMUNICATION_I_NET_ADJ_CALLBACK_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_service.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_service.h new file mode 100644 index 00000000..76ff11e4 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_adj_service.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef NETMANAGER_I_NET_ADJ_SERVICE_H +#define NETMANAGER_I_NET_ADJ_SERVICE_H + +#include + +#include "conn_ipc_interface_code.h" +#include "iremote_broker.h" +#include "i_net_adj_callback.h" +#include "net_adj_iface_info.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetAdjService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetAdjService"); + +public: + virtual int32_t SystemReady() = 0; + virtual int32_t AddNetAdjIface(const sptr &adjIface) = 0; + virtual int32_t RemoveNetAdjIface(const std::string &ifaceName) = 0; + virtual int32_t RegisterAdjIfaceCallback(const sptr &callback) = 0; + virtual int32_t UnregisterAdjIfaceCallback(const sptr &callback) = 0; + virtual int32_t UpdateNetAdjInfo(const std::string &iface, const sptr &adjIfaceINfo) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NETMANAGER_I_NET_ADJ_SERVICE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_callback.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_callback.h new file mode 100644 index 00000000..5d42bb66 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_callback.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_CONN_CALLBACK_H +#define I_NET_CONN_CALLBACK_H + +#include "conn_ipc_interface_code.h" +#include "iremote_broker.h" + +#include "net_specifier.h" +#include "net_link_info.h" +#include "net_handle.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetConnCallback : public IRemoteBroker { +public: + virtual ~INetConnCallback() = default; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetConnCallback"); + +public: + virtual int32_t NetAvailable(sptr &netHandle) = 0; + virtual int32_t NetCapabilitiesChange(sptr &netHandle, const sptr &netAllCap) = 0; + virtual int32_t NetConnectionPropertiesChange(sptr &netHandle, const sptr &info) = 0; + virtual int32_t NetLost(sptr &netHandle) = 0; + virtual int32_t NetUnavailable() = 0; + virtual int32_t NetBlockStatusChange(sptr &netHandle, bool blocked) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_CONN_CALLBACK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_service.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_service.h new file mode 100644 index 00000000..8e6b2562 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_conn_service.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_CONN_SERVICE_H +#define I_NET_CONN_SERVICE_H + +#include + +#include "iremote_broker.h" + +#include "http_proxy.h" +#include "i_net_conn_callback.h" +#include "i_net_detection_callback.h" +#include "i_net_interface_callback.h" +#include "i_net_supplier_callback.h" +#include "net_conn_constants.h" +#include "net_interface_config.h" +#include "net_link_info.h" +#include "net_specifier.h" +#include "net_supplier_info.h" +#include "conn_ipc_interface_code.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetConnService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetConnService"); + +public: + virtual int32_t SystemReady() = 0; + virtual int32_t SetInternetPermission(uint32_t uid, uint8_t allow) = 0; + virtual int32_t RegisterNetSupplier(NetBearType bearerType, const std::string &ident, + const std::set &netCaps, uint32_t &supplierId) = 0; + virtual int32_t UnregisterNetSupplier(uint32_t supplierId) = 0; + virtual int32_t RegisterNetSupplierCallback(uint32_t supplierId, const sptr &callback) = 0; + virtual int32_t RegisterNetConnCallback(const sptr &callback) = 0; + virtual int32_t RegisterNetConnCallback(const sptr &netSpecifier, + const sptr &callback, const uint32_t &timeoutMS) = 0; + virtual int32_t UnregisterNetConnCallback(const sptr &callback) = 0; + virtual int32_t UpdateNetStateForTest(const sptr &netSpecifier, int32_t netState) = 0; + virtual int32_t UpdateNetSupplierInfo(uint32_t supplierId, const sptr &netSupplierInfo) = 0; + virtual int32_t UpdateNetLinkInfo(uint32_t supplierId, const sptr &netLinkInfo) = 0; + virtual int32_t GetIfaceNames(NetBearType bearerType, std::list &ifaceNames) = 0; + virtual int32_t GetIfaceNameByType(NetBearType bearerType, const std::string &ident, std::string &ifaceName) = 0; + virtual int32_t RegisterNetDetectionCallback(int32_t netId, const sptr &callback) = 0; + virtual int32_t UnRegisterNetDetectionCallback(int32_t netId, const sptr &callback) = 0; + virtual int32_t NetDetection(int32_t netId) = 0; + virtual int32_t GetDefaultNet(int32_t &netId) = 0; + virtual int32_t HasDefaultNet(bool &flag) = 0; + virtual int32_t GetAddressesByName(const std::string &host, int32_t netId, std::vector &addrList) = 0; + virtual int32_t GetAddressByName(const std::string &host, int32_t netId, INetAddr &addr) = 0; + virtual int32_t GetSpecificNet(NetBearType bearerType, std::list &netIdList) = 0; + virtual int32_t GetAllNets(std::list &netIdList) = 0; + virtual int32_t GetSpecificUidNet(int32_t uid, int32_t &netId) = 0; + virtual int32_t GetConnectionProperties(int32_t netId, NetLinkInfo &info) = 0; + virtual int32_t GetNetCapabilities(int32_t netId, NetAllCapabilities &netAllCap) = 0; + virtual int32_t BindSocket(int32_t socket_fd, int32_t netId) = 0; + virtual int32_t SetAirplaneMode(bool state) = 0; + virtual int32_t IsDefaultNetMetered(bool &isMetered) = 0; + virtual int32_t SetGlobalHttpProxy(const HttpProxy &httpProxy) = 0; + virtual int32_t GetGlobalHttpProxy(HttpProxy &httpProxy) = 0; + virtual int32_t GetDefaultHttpProxy(int32_t bindNetId, HttpProxy &httpProxy) = 0; + virtual int32_t GetNetIdByIdentifier(const std::string &ident, std::list &netIdList) = 0; + virtual int32_t SetAppNet(int32_t netId) = 0; + virtual int32_t RegisterNetInterfaceCallback(const sptr &callback) = 0; + virtual int32_t GetNetInterfaceConfiguration(const std::string &iface, NetInterfaceConfiguration &config) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_CONN_SERVICE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_detection_callback.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_detection_callback.h new file mode 100644 index 00000000..fc187f5b --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_detection_callback.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_DETECTION_CALLBACK_H +#define I_NET_DETECTION_CALLBACK_H + +#include "conn_ipc_interface_code.h" +#include "iremote_broker.h" + +#include "net_conn_constants.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetDetectionCallback : public IRemoteBroker { +public: + virtual ~INetDetectionCallback() = default; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetDetectionCallback"); + +public: + virtual int32_t OnNetDetectionResultChanged( + NetDetectionResultCode detectionResult, const std::string &urlRedirect) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_DETECTION_CALLBACK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_interface_callback.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_interface_callback.h new file mode 100644 index 00000000..3419603f --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_interface_callback.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_INTERFACE_CALLBACK_H +#define I_NET_INTERFACE_CALLBACK_H + +#include "conn_ipc_interface_code.h" +#include "iremote_broker.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetInterfaceStateCallback : public IRemoteBroker { +public: + virtual ~INetInterfaceStateCallback() = default; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetInterfaceStateCallback"); + +public: + virtual int32_t OnInterfaceAddressUpdated(const std::string &addr, const std::string &ifName, int32_t flags, + int32_t scope) = 0; + virtual int32_t OnInterfaceAddressRemoved(const std::string &addr, const std::string &ifName, int32_t flags, + int32_t scope) = 0; + virtual int32_t OnInterfaceAdded(const std::string &ifName) = 0; + virtual int32_t OnInterfaceRemoved(const std::string &ifName) = 0; + virtual int32_t OnInterfaceChanged(const std::string &ifName, bool up) = 0; + virtual int32_t OnInterfaceLinkStateChanged(const std::string &ifName, bool up) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_INTERFACE_CALLBACK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_supplier_callback.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_supplier_callback.h new file mode 100644 index 00000000..08b17e0e --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/i_net_supplier_callback.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_SUPPLIER_CALLBACK_H +#define I_NET_SUPPLIER_CALLBACK_H + +#include +#include + +#include "conn_ipc_interface_code.h" +#include "iremote_broker.h" + +#include "net_all_capabilities.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetSupplierCallback : public IRemoteBroker { +public: + virtual ~INetSupplierCallback() = default; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetSupplierCallback"); + +public: + virtual int32_t RequestNetwork(const std::string &ident, const std::set &netCaps) = 0; + virtual int32_t ReleaseNetwork(const std::string &ident, const std::set &netCaps) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_SUPPLIER_CALLBACK_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_callback_stub.h new file mode 100644 index 00000000..8bc7fc87 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_callback_stub.h @@ -0,0 +1,57 @@ +/* + * 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 NET_CONN_CALLBACK_STUB_H +#define NET_CONN_CALLBACK_STUB_H + +#include + +#include "i_net_conn_callback.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetConnCallbackStub : public IRemoteStub { +public: + NetConnCallbackStub(); + virtual ~NetConnCallbackStub(); + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +public: + int32_t NetAvailable(sptr &netHandle) override; + int32_t NetCapabilitiesChange(sptr &netHandle, const sptr &netAllCap) override; + int32_t NetConnectionPropertiesChange(sptr &netHandle, const sptr &info) override; + int32_t NetLost(sptr &netHandle) override; + int32_t NetUnavailable() override; + int32_t NetBlockStatusChange(sptr &netHandle, bool blocked) override; + +private: + using NetConnCallbackFunc = int32_t (NetConnCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t OnNetAvailable(MessageParcel &data, MessageParcel &reply); + int32_t OnNetCapabilitiesChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetConnectionPropertiesChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetLost(MessageParcel &data, MessageParcel &reply); + int32_t OnNetUnavailable(MessageParcel &data, MessageParcel &reply); + int32_t OnNetBlockStatusChange(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_CONN_CALLBACK_STUB_H diff --git a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_conn_client.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_service_proxy.h similarity index 30% rename from mock/innerkits/netmanager_base/net_conn_manager_if/include/net_conn_client.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_service_proxy.h index 60d971fb..0446d08b 100644 --- a/mock/innerkits/netmanager_base/net_conn_manager_if/include/net_conn_client.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_conn_service_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,79 +13,64 @@ * limitations under the License. */ -#ifndef NET_CONN_MANAGER_H -#define NET_CONN_MANAGER_H +#ifndef NET_CONN_SERVICE_PROXY_H +#define NET_CONN_SERVICE_PROXY_H -#include -#include - -#include "parcel.h" -#include "singleton.h" +#include "iremote_proxy.h" #include "i_net_conn_service.h" -#include "i_net_supplier_callback.h" -#include "net_supplier_callback_base.h" -#include "net_link_info.h" -#include "net_specifier.h" -#include "net_handle.h" namespace OHOS { -namespace nmd { - class FwmarkClient; -} namespace NetManagerStandard { -class NetConnClient { - DECLARE_DELAYED_SINGLETON(NetConnClient) - +class NetConnServiceProxy : public IRemoteProxy { public: - int32_t SystemReady(); - int32_t RegisterNetSupplier(NetBearType bearerType, const std::string &ident, - const std::set &netCaps, uint32_t &supplierId); - int32_t UnregisterNetSupplier(uint32_t supplierId); - int32_t RegisterNetSupplierCallback(uint32_t supplierId, const sptr &callback); - int32_t UpdateNetSupplierInfo(uint32_t supplierId, const sptr &netSupplierInfo); - int32_t UpdateNetLinkInfo(uint32_t supplierId, const sptr &netLinkInfo); - int32_t RegisterNetConnCallback(const sptr &callback); - int32_t RegisterNetConnCallback(const sptr &netSpecifier, - const sptr &callback, const uint32_t &timeoutMS); - int32_t UnregisterNetConnCallback(const sptr &callback); - int32_t GetDefaultNet(NetHandle &netHandle); - int32_t HasDefaultNet(bool &flag); - int32_t GetAllNets(std::list> &netList); - int32_t GetConnectionProperties(const NetHandle &netHandle, NetLinkInfo &info); - int32_t GetNetCapabilities(const NetHandle &netHandle, NetAllCapabilities &netAllCap); - int32_t GetAddressesByName(const std::string &host, int32_t netId, std::vector &addrList); - int32_t GetAddressByName(const std::string &host, int32_t netId, INetAddr &addr); - int32_t BindSocket(int32_t socket_fd, int32_t netId); - int32_t NetDetection(const NetHandle &netHandle); - int32_t SetAirplaneMode(bool state); - int32_t RestoreFactoryData(); - -private: - class NetConnDeathRecipient : public IRemoteObject::DeathRecipient { - public: - explicit NetConnDeathRecipient(NetConnClient &client) : client_(client) {} - ~NetConnDeathRecipient() override = default; - void OnRemoteDied(const wptr &remote) override - { - client_.OnRemoteDied(remote); - } - - private: - NetConnClient &client_; - }; + explicit NetConnServiceProxy(const sptr &impl); + virtual ~NetConnServiceProxy(); + int32_t SystemReady() override; + int32_t SetInternetPermission(uint32_t uid, uint8_t allow) override; + int32_t RegisterNetSupplier(NetBearType bearerType, const std::string &ident, const std::set &netCaps, + uint32_t &supplierId) override; + int32_t UnregisterNetSupplier(uint32_t supplierId) override; + int32_t RegisterNetSupplierCallback(uint32_t supplierId, const sptr &callback) override; + int32_t RegisterNetConnCallback(const sptr &callback) override; + int32_t RegisterNetConnCallback(const sptr &netSpecifier, const sptr &callback, + const uint32_t &timeoutMS) override; + int32_t UnregisterNetConnCallback(const sptr &callback) override; + int32_t UpdateNetStateForTest(const sptr &netSpecifier, int32_t netState) override; + int32_t UpdateNetSupplierInfo(uint32_t supplierId, const sptr &netSupplierInfo) override; + int32_t UpdateNetLinkInfo(uint32_t supplierId, const sptr &netLinkInfo) override; + int32_t GetDefaultNet(int32_t &netId) override; + int32_t HasDefaultNet(bool &flag) override; + int32_t GetIfaceNames(NetBearType bearerType, std::list &ifaceNames) override; + int32_t GetIfaceNameByType(NetBearType bearerType, const std::string &ident, std::string &ifaceName) override; + int32_t RegisterNetDetectionCallback(int32_t netId, const sptr &callback) override; + int32_t UnRegisterNetDetectionCallback(int32_t netId, const sptr &callback) override; + int32_t NetDetection(int32_t netId) override; + int32_t GetAddressesByName(const std::string &host, int32_t netId, std::vector &addrList) override; + int32_t GetAddressByName(const std::string &host, int32_t netId, INetAddr &addr) override; + int32_t GetSpecificNet(NetBearType bearerType, std::list &netIdList) override; + int32_t GetAllNets(std::list &netIdList) override; + int32_t GetSpecificUidNet(int32_t uid, int32_t &netId) override; + int32_t GetConnectionProperties(int32_t netId, NetLinkInfo &info) override; + int32_t GetNetCapabilities(int32_t netId, NetAllCapabilities &netAllCap) override; + int32_t BindSocket(int32_t socket_fd, int32_t netId) override; + int32_t SetAirplaneMode(bool state) override; + int32_t IsDefaultNetMetered(bool &isMetered) override; + int32_t SetGlobalHttpProxy(const HttpProxy &httpProxy) override; + int32_t GetGlobalHttpProxy(HttpProxy &httpProxy) override; + int32_t GetDefaultHttpProxy(int32_t bindNetId, HttpProxy &httpProxy) override; + int32_t GetNetIdByIdentifier(const std::string &ident, std::list &netIdList) override; + int32_t SetAppNet(int32_t netId) override; + int32_t RegisterNetInterfaceCallback(const sptr &callback) override; + int32_t GetNetInterfaceConfiguration(const std::string &iface, NetInterfaceConfiguration &config) override; private: - sptr GetProxy(); - void OnRemoteDied(const wptr &remote); + bool WriteInterfaceToken(MessageParcel &data); + int32_t GetNetCapData(MessageParcel &reply, NetAllCapabilities &netAllCap); private: - std::mutex mutex_; - sptr NetConnService_; - sptr deathRecipient_; - std::map> netSupplierCallback_; + static inline BrokerDelegator delegator_; }; } // namespace NetManagerStandard } // namespace OHOS - -#endif // NET_CONN_MANAGER_H \ No newline at end of file +#endif // NET_CONN_SERVICE_PROXY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_detection_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_detection_callback_stub.h new file mode 100644 index 00000000..8129102e --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_detection_callback_stub.h @@ -0,0 +1,46 @@ +/* + * 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 NET_DETECTION_CALLBACK_STUB_H +#define NET_DETECTION_CALLBACK_STUB_H + +#include + +#include "iremote_stub.h" + +#include "i_net_detection_callback.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetDetectionCallbackStub : public IRemoteStub { +public: + NetDetectionCallbackStub(); + virtual ~NetDetectionCallbackStub(); + + int32_t OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using NetDetectionCallbackFunc = int32_t (NetDetectionCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t OnNetDetectionResult(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_DETECTION_CALLBACK_STUB_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_interface_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_interface_callback_stub.h new file mode 100644 index 00000000..8c778758 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_interface_callback_stub.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_INTERFACE_CALLBACK_STUB_H +#define NET_INTERFACE_CALLBACK_STUB_H + +#include "i_net_interface_callback.h" + +#include + +#include "iremote_stub.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetInterfaceStateCallbackStub : public IRemoteStub { +public: + NetInterfaceStateCallbackStub(); + virtual ~NetInterfaceStateCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + int32_t OnInterfaceAddressUpdated(const std::string &addr, const std::string &ifName, int32_t flags, + int32_t scope) override; + int32_t OnInterfaceAddressRemoved(const std::string &addr, const std::string &ifName, int32_t flags, + int32_t scope) override; + int32_t OnInterfaceAdded(const std::string &ifName) override; + int32_t OnInterfaceRemoved(const std::string &ifName) override; + int32_t OnInterfaceChanged(const std::string &ifName, bool up) override; + int32_t OnInterfaceLinkStateChanged(const std::string &ifName, bool up) override; + +private: + using NetInterfaceStateCallbackFunc = int32_t (NetInterfaceStateCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t CmdInterfaceAddressUpdated(MessageParcel &data, MessageParcel &reply); + int32_t CmdInterfaceAddressRemoved(MessageParcel &data, MessageParcel &reply); + int32_t CmdInterfaceAdded(MessageParcel &data, MessageParcel &reply); + int32_t CmdInterfaceRemoved(MessageParcel &data, MessageParcel &reply); + int32_t CmdInterfaceChanged(MessageParcel &data, MessageParcel &reply); + int32_t CmdInterfaceLinkStateChanged(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_INTERFACE_CALLBACK_STUB_H diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_supplier_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_supplier_callback_stub.h new file mode 100644 index 00000000..4cba1212 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/proxy/net_supplier_callback_stub.h @@ -0,0 +1,56 @@ +/* + * 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 NET_SUPPLIER_CALLBACK_STUB_H +#define NET_SUPPLIER_CALLBACK_STUB_H + +#include +#include + +#include "iremote_stub.h" + +#include "i_net_supplier_callback.h" +#include "net_supplier_callback_base.h" +#include "net_all_capabilities.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetSupplierCallbackStub : public IRemoteStub { +public: + NetSupplierCallbackStub(); + virtual ~NetSupplierCallbackStub(); + + void RegisterSupplierCallbackImpl(const sptr &callback); + + int32_t OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + int32_t RequestNetwork(const std::string &ident, const std::set &netCaps) override; + int32_t ReleaseNetwork(const std::string &ident, const std::set &netCaps) override; + +private: + using NetSupplierCallbackFunc = int32_t (NetSupplierCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t OnRequestNetwork(MessageParcel &data, MessageParcel &reply); + int32_t OnReleaseNetwork(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; + sptr callback_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_SUPPLIER_CALLBACK_STUB_H diff --git a/mock/innerkits/netmanager_base/net_conn_manager_if/include/route.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/route.h similarity index 88% rename from mock/innerkits/netmanager_base/net_conn_manager_if/include/route.h rename to mock/innerkits/netmanager_base/innerkits/netconnclient/include/route.h index 40a2349c..b875c4f8 100644 --- a/mock/innerkits/netmanager_base/net_conn_manager_if/include/route.h +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/route.h @@ -16,8 +16,13 @@ #ifndef ROUTE_H #define ROUTE_H +#include +#include #include +#include "parcel.h" +#include "refbase.h" + #include "inet_addr.h" namespace OHOS { @@ -28,7 +33,7 @@ enum { RTN_THROW = 9 }; -struct Route : public Parcelable { +struct Route final: public Parcelable { std::string iface_; INetAddr destination_; INetAddr gateway_; @@ -40,7 +45,7 @@ struct Route : public Parcelable { bool operator==(const Route& obj) const; - virtual bool Marshalling(Parcel &parcel) const override; + bool Marshalling(Parcel &parcel) const override; static sptr Unmarshalling(Parcel &parcel); static bool Marshalling(Parcel &parcel, const sptr &object); std::string ToString(const std::string &tab) const; diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/include/socket_permission.h b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/socket_permission.h new file mode 100644 index 00000000..4eee4695 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/include/socket_permission.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETMANAGER_BASE_SOCKET_PERMISSION_H +#define NETMANAGER_BASE_SOCKET_PERMISSION_H + +#include + +int32_t SetInternetPermission(uint32_t uid, uint8_t allow); +#endif /* NETMANAGER_BASE_SOCKET_PERMISSION_H */ diff --git a/mock/innerkits/netmanager_base/innerkits/netconnclient/libnetconn_kits.map b/mock/innerkits/netmanager_base/innerkits/netconnclient/libnetconn_kits.map new file mode 100644 index 00000000..b21944bb --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netconnclient/libnetconn_kits.map @@ -0,0 +1,145 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{ + global: + extern "C++" { + VTT?for?OHOS::NetManagerStandard::NetAllCapabilities; + vtable?for?OHOS::NetManagerStandard::NetAllCapabilities; + "OHOS::NetManagerStandard::NetAllCapabilities::operator=(OHOS::NetManagerStandard::NetAllCapabilities const&)"; + "OHOS::NetManagerStandard::NetAllCapabilities::NetAllCapabilities(OHOS::NetManagerStandard::NetAllCapabilities const&)"; + VTT?for?OHOS::NetManagerStandard::HttpProxy; + vtable?for?OHOS::NetManagerStandard::HttpProxy; + "OHOS::NetManagerStandard::HttpProxy::HttpProxy()"; + VTT?for?OHOS::NetManagerStandard::NetLinkInfo; + vtable?for?OHOS::NetManagerStandard::NetLinkInfo; + "OHOS::NetManagerStandard::INetAddr::Marshalling(OHOS::Parcel&) const"; + "OHOS::NetManagerStandard::INetAddr::Unmarshalling(OHOS::Parcel&)"; + "OHOS::NetManagerStandard::Route::Marshalling(OHOS::Parcel&) const"; + "OHOS::NetManagerStandard::Route::Unmarshalling(OHOS::Parcel&)"; + "OHOS::NetManagerStandard::NetHandle::BindSocket(int)"; + "OHOS::NetManagerStandard::NetConnClient::HasDefaultNet(bool&)"; + "OHOS::NetManagerStandard::NetConnClient::IsDefaultNetMetered(bool&)"; + "OHOS::NetManagerStandard::NetConnClient::GetInstance()"; + "OHOS::NetManagerStandard::NetConnClient::GetConnectionProperties(OHOS::NetManagerStandard::NetHandle const&, OHOS::NetManagerStandard::NetLinkInfo&)"; + "OHOS::NetManagerStandard::NetConnClient::GetAllNets(std::__h::list, std::__h::allocator>>&)"; + "OHOS::NetManagerStandard::NetConnClient::SetAirplaneMode(bool)"; + "OHOS::NetManagerStandard::NetConnClient::NetDetection(OHOS::NetManagerStandard::NetHandle const&)"; + "OHOS::NetManagerStandard::NetConnClient::GetGlobalHttpProxy(OHOS::NetManagerStandard::HttpProxy&)"; + "OHOS::NetManagerStandard::NetConnClient::InterfaceSetIffUp(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetConnClient::SetGlobalHttpProxy(OHOS::NetManagerStandard::HttpProxy const&)"; + "OHOS::NetManagerStandard::NetConnClient::GetAppNet(int&)"; + "OHOS::NetManagerStandard::NetConnClient::SetAppNet(int)"; + "OHOS::NetManagerStandard::NetConnClient::GetDefaultNet(OHOS::NetManagerStandard::NetHandle&)"; + "OHOS::NetManagerStandard::NetConnClient::GetNetCapabilities(OHOS::NetManagerStandard::NetHandle const&, OHOS::NetManagerStandard::NetAllCapabilities&)"; + "OHOS::NetManagerStandard::NetConnClient::GetAddressesByName(std::__h::basic_string, std::__h::allocator> const&, int, std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetConnClient::GetAddressByName(std::__h::basic_string, std::__h::allocator> const&, int, OHOS::NetManagerStandard::INetAddr&)"; + "OHOS::NetManagerStandard::NetConnClient::BindSocket(int, int)"; + "OHOS::NetManagerStandard::NetConnClient::OnRemoteDied(OHOS::wptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::NetConnClient()"; + "OHOS::NetManagerStandard::NetConnClient::~NetConnClient()"; + "OHOS::NetManagerStandard::NetConnClient::RegisterNetConnCallback(OHOS::sptr const&, OHOS::sptr const&, unsigned int const&)"; + "OHOS::NetManagerStandard::NetConnClient::RegisterNetConnCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::SetInternetPermission(unsigned int, unsigned char)"; + "OHOS::NetManagerStandard::NetConnClient::UnregisterNetConnCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::RegisterNetSupplier(OHOS::NetManagerStandard::NetBearType, std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&, unsigned int&)"; + "OHOS::NetManagerStandard::NetConnClient::RegisterNetSupplierCallback(unsigned int, OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::UnregisterNetSupplier(unsigned int)"; + "OHOS::NetManagerStandard::NetConnClient::UpdateNetSupplierInfo(unsigned int, OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::UpdateNetLinkInfo(unsigned int, OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnClient::SystemReady()"; + "OHOS::NetManagerStandard::NetConnClient::GetDefaultHttpProxy(OHOS::NetManagerStandard::HttpProxy&)"; + "OHOS::NetManagerStandard::NetConnClient::GetNetIdByIdentifier(std::__h::basic_string, std::__h::allocator> const&, std::__h::list>&)"; + "OHOS::NetManagerStandard::NetConnClient::GetNetInterfaceConfiguration(std::__h::basic_string, std::__h::allocator> const&, OHOS::NetManagerStandard::NetInterfaceConfiguration&)"; + "OHOS::NetManagerStandard::NetConnClient::RegisterNetInterfaceCallback(OHOS::sptr const&)"; + VTT?for?OHOS::NetManagerStandard::NetSpecifier; + vtable?for?OHOS::NetManagerStandard::NetSpecifier; + "OHOS::NetManagerStandard::NetLinkInfo::NetLinkInfo(OHOS::NetManagerStandard::NetLinkInfo const&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::~NetConnCallbackStub()"; + "OHOS::NetManagerStandard::NetConnCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::~NetConnCallbackStub()"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetAvailable(OHOS::sptr&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetCapabilitiesChange(OHOS::sptr&, OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetConnectionPropertiesChange(OHOS::sptr&, OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetLost(OHOS::sptr&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetUnavailable()"; + "OHOS::NetManagerStandard::NetConnCallbackStub::OnNetLost(OHOS::MessageParcel&, OHOS::MessageParcel&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::OnNetBlockStatusChange(OHOS::MessageParcel&, OHOS::MessageParcel&)"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetConnCallbackStub()"; + "OHOS::NetManagerStandard::NetConnCallbackStub::NetBlockStatusChange(OHOS::sptr&, bool)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::~NetConnCallbackStub()"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetAvailable(OHOS::sptr&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetCapabilitiesChange(OHOS::sptr&, OHOS::sptr const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetConnectionPropertiesChange(OHOS::sptr&, OHOS::sptr const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetLost(OHOS::sptr&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetUnavailable()"; + "non-virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::NetBlockStatusChange(OHOS::sptr&, bool)"; + "virtual thunk to OHOS::NetManagerStandard::NetConnCallbackStub::~NetConnCallbackStub()"; + "OHOS::NetManagerStandard::NetAllCapabilities::ToString(std::__h::basic_string, std::__h::allocator> const&) const"; + "OHOS::NetManagerStandard::NetLinkInfo::ToString(std::__h::basic_string, std::__h::allocator> const&) const"; + VTT?for?OHOS::NetManagerStandard::INetAddr; + vtable?for?OHOS::NetManagerStandard::INetAddr; + VTT?for?OHOS::NetManagerStandard::NetSupplierInfo; + vtable?for?OHOS::NetManagerStandard::NetSupplierInfo; + VTT?for?OHOS::NetManagerStandard::Route; + vtable?for?OHOS::NetManagerStandard::Route; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceTxPackets(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceRxPackets(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackBase::RequestNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackBase::ReleaseNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::NetSupplierCallbackStub()"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::~NetSupplierCallbackStub()"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::RequestNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::ReleaseNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetSupplierCallbackStub::RequestNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetSupplierCallbackStub::ReleaseNetwork(std::__h::basic_string, std::__h::allocator> const&, std::__h::set, std::__h::allocator> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetSupplierCallbackStub::~NetSupplierCallbackStub()"; + "virtual thunk to OHOS::NetManagerStandard::NetSupplierCallbackStub::~NetSupplierCallbackStub()"; + vtable?for?OHOS::NetManagerStandard::NetSupplierCallbackBase; + "OHOS::NetManagerStandard::NetDetectionCallbackStub::NetDetectionCallbackStub()"; + "OHOS::NetManagerStandard::NetDetectionCallbackStub::OnNetDetectionResult(OHOS::MessageParcel&, OHOS::MessageParcel&)"; + "OHOS::NetManagerStandard::NetDetectionCallbackStub::~NetDetectionCallbackStub()"; + "OHOS::NetManagerStandard::NetDetectionCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetDetectionCallbackStub::~NetDetectionCallbackStub()"; + "virtual thunk to OHOS::NetManagerStandard::NetDetectionCallbackStub::~NetDetectionCallbackStub()"; + "OHOS::NetManagerStandard::NetHandle::GetAddressesByName(std::__h::basic_string, std::__h::allocator> const&, std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetHandle::GetAddressByName(std::__h::basic_string, std::__h::allocator> const&, OHOS::NetManagerStandard::INetAddr&)"; + "OHOS::NetManagerStandard::NetSupplierCallbackStub::RegisterSupplierCallbackImpl(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::HttpProxy::GetHost() const"; + "OHOS::NetManagerStandard::HttpProxy::GetPort() const"; + "OHOS::NetManagerStandard::HttpProxy::Unmarshalling(OHOS::Parcel&, OHOS::NetManagerStandard::HttpProxy&)"; + "OHOS::NetManagerStandard::HttpProxy::Marshalling(OHOS::Parcel&) const"; + "OHOS::NetManagerStandard::HttpProxy::GetExclusionList() const"; + "OHOS::NetManagerStandard::HttpProxy::HttpProxy(std::__h::basic_string, std::__h::allocator>, unsigned short, std::__h::list, std::__h::allocator>, std::__h::allocator, std::__h::allocator>>> const&)"; + "OHOS::NetManagerStandard::NetConnServiceProxy::NetConnServiceProxy(OHOS::sptr const&)"; + VTT?for?OHOS::NetManagerStandard::NetInterfaceStateCallbackStub; + vtable?for?OHOS::NetManagerStandard::NetInterfaceStateCallbackStub; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::NetInterfaceStateCallbackStub()"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAddressUpdated(std::__h::basic_string, std::__h::allocator> const&, std::__h::basic_string, std::__h::allocator> const&, int, int)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAddressRemoved(std::__h::basic_string, std::__h::allocator> const&, std::__h::basic_string, std::__h::allocator> const&, int, int)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAdded(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceRemoved(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceChanged(std::__h::basic_string, std::__h::allocator> const&, bool)"; + "OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceLinkStateChanged(std::__h::basic_string, std::__h::allocator> const&, bool)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAddressUpdated(std::__h::basic_string, std::__h::allocator> const&, std::__h::basic_string, std::__h::allocator> const&, int, int)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAddressRemoved(std::__h::basic_string, std::__h::allocator> const&, std::__h::basic_string, std::__h::allocator> const&, int, int)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceAdded(std::__h::basic_string, std::__h::allocator> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceRemoved(std::__h::basic_string, std::__h::allocator> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceChanged(std::__h::basic_string, std::__h::allocator> const&, bool)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetInterfaceStateCallbackStub::OnInterfaceLinkStateChanged(std::__h::basic_string, std::__h::allocator> const&, bool)"; + }; + local: + *; +}; \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/BUILD.gn b/mock/innerkits/netmanager_base/innerkits/netmanagernative/BUILD.gn new file mode 100644 index 00000000..0edc01dc --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/BUILD.gn @@ -0,0 +1,97 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/netmanager_base/netmanager_base_config.gni") + +config("net_native_manager_if_config") { + # header file path + include_dirs = [ + "$INNERKITS_ROOT/include", + "$INNERKITS_ROOT/netstatsclient/include/proxy", + "$INNERKITS_ROOT/netstatsclient/include", + "$INNERKITS_ROOT/netmanagernative/include", + "$NETSYSNATIVE_SOURCE_DIR/include/netsys", + ] + + cflags = [] + if (is_double_framework) { + cflags += [ "-DCONFIG_DUAL_FRAMEWORK" ] + } + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + if (is_standard_system) { + cflags += [ "-DCONFIG_STANDARD_SYSTEM" ] + } + if (defined(build_public_version) && build_public_version) { + cflags += [ "-DBUILD_PUBLIC_VERSION" ] + } +} + +ohos_source_set("net_native_parcel") { + sources = [ + "$NETSYSNATIVE_INNERKITS_SOURCE_DIR/dhcp_result_parcel.cpp", + "$NETSYSNATIVE_INNERKITS_SOURCE_DIR/uid_range.cpp", + ] + + include_dirs = [ "$INNERKITS_ROOT/netmanagernative/include" ] + + deps = [ "$NETMANAGER_BASE_ROOT/utils:net_manager_common" ] + external_deps = [ "c_utils:utils" ] + external_deps += [ "hilog:libhilog" ] + + part_name = "netmanager_base" + subsystem_name = "communication" +} + +ohos_shared_library("net_native_manager_if") { + sources = [ + "$NETSYSNATIVE_INNERKITS_SOURCE_DIR/netsys_addr_info_parcel.cpp", + "$NETSYSNATIVE_INNERKITS_SOURCE_DIR/netsys_native_service_proxy.cpp", + "$NETSYSNATIVE_INNERKITS_SOURCE_DIR/notify_callback_proxy.cpp", + ] + + include_dirs = [ + "$NETMANAGER_BASE_ROOT/utils/log/include", + "$NETSYSCONTROLLER_ROOT_DIR/include/", + ] + + public_configs = [ ":net_native_manager_if_config" ] + + deps = [ + ":net_native_parcel", + "$INNERKITS_ROOT/netstatsclient:net_stats_manager_if", + "$NETSYSCONTROLLER_ROOT_DIR:netsys_controller", + ] + + external_deps = [ + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + defines = [ + "NETMGR_LOG_TAG = \"NetNativeMnager\"", + "LOG_DOMAIN = 0xD0015B0", + ] + + if (enable_netmgr_debug) { + defines += [ "NETMGR_DEBUG" ] + } + + external_deps += [ "hilog:libhilog" ] + + innerapi_tags = [ "platformsdk" ] + part_name = "netmanager_base" + subsystem_name = "communication" +} diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/dhcp_result_parcel.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/dhcp_result_parcel.h new file mode 100644 index 00000000..fbc5c30d --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/dhcp_result_parcel.h @@ -0,0 +1,40 @@ +/* + * 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 DHCP_RESULT_PARCEL_H +#define DHCP_RESULT_PARCEL_H + +#include +#include "parcel.h" + +namespace OHOS { +namespace NetsysNative { +struct DhcpResultParcel : public Parcelable { + DhcpResultParcel(); + ~DhcpResultParcel() {} + + std::string iface_; + std::string ipAddr_; + std::string gateWay_; + std::string subNet_; + std::string route1_; + std::string route2_; + std::string dns1_; + std::string dns2_; + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(Parcel &parcel); +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // DHCP_RESULT_PARCEL_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark.h new file mode 100644 index 00000000..b03ba9e7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_FWMARK_H +#define INCLUDE_FWMARK_H + +#include + +#include "network_permission.h" + +namespace OHOS { +namespace nmd { +union Fwmark { + uint32_t intValue; + struct { + uint16_t netId : 16; + bool explicitlySelected : 1; + bool protectedFromVpn : 1; + NetworkPermission permission : 2; + bool uidBillingDone : 1; + }; + constexpr Fwmark() : intValue(0) {} + static inline uint32_t GetUidBillingMask() + { + Fwmark m; + m.uidBillingDone = true; + return m.intValue; + } +}; +static constexpr uint32_t FWMARK_NET_ID_MASK = 0xffff; +static const struct sockaddr_un FWMARK_SERVER_PATH = {AF_UNIX, "/dev/unix/socket/fwmarkd"}; +} // namespace nmd +} // namespace OHOS +#endif // INCLUDE_FWMARK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark_command.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark_command.h new file mode 100644 index 00000000..85ca27be --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/fwmark_command.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_FWMARK_COMMAND_H +#define INCLUDE_FWMARK_COMMAND_H + +namespace OHOS { +namespace nmd { +struct FwmarkCommand { + enum CmdId { + SELECT_NETWORK, + PROTECT_FROM_VPN, + } cmdId; + uint32_t netId; +}; +} // namespace nmd +} // namespace OHOS +#endif // INCLUDE_FWMARK_COMMAND_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_netsys_service.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_netsys_service.h new file mode 100644 index 00000000..d8c200c7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_netsys_service.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef I_NETSYS_SERVICE_H +#define I_NETSYS_SERVICE_H + +#include +#include + +#include "dns_config_client.h" +#include "i_notify_callback.h" +#include "interface_type.h" +#include "iremote_broker.h" +#include "net_stats_info.h" +#include "network_sharing.h" +#include "netsys_ipc_interface_code.h" +#include "route_type.h" +#include "uid_range.h" + +namespace OHOS { +namespace NetsysNative { +using namespace nmd; +using namespace OHOS::NetManagerStandard; +class INetsysService : public IRemoteBroker { +public: + virtual int32_t SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMsec, uint8_t retryCount, + const std::vector &servers, + const std::vector &domains) = 0; + virtual int32_t GetResolverConfig(uint16_t netId, std::vector &servers, + std::vector &domains, uint16_t &baseTimeoutMsec, + uint8_t &retryCount) = 0; + virtual int32_t CreateNetworkCache(uint16_t netId) = 0; + virtual int32_t DestroyNetworkCache(uint16_t netId) = 0; + virtual int32_t GetAddrInfo(const std::string &hostName, const std::string &serverName, const AddrInfo &hints, + uint16_t netId, std::vector &res) = 0; + virtual int32_t SetInterfaceMtu(const std::string &interfaceName, int mtu) = 0; + virtual int32_t GetInterfaceMtu(const std::string &interfaceName) = 0; + + virtual int32_t RegisterNotifyCallback(sptr &callback) = 0; + virtual int32_t UnRegisterNotifyCallback(sptr &callback) = 0; + + virtual int32_t NetworkAddRoute(int32_t netId, const std::string &interfaceName, const std::string &destination, + const std::string &nextHop) = 0; + virtual int32_t NetworkRemoveRoute(int32_t netId, const std::string &interfaceName, const std::string &destination, + const std::string &nextHop) = 0; + virtual int32_t NetworkAddRouteParcel(int32_t netId, const RouteInfoParcel &routeInfo) = 0; + virtual int32_t NetworkRemoveRouteParcel(int32_t netId, const RouteInfoParcel &routeInfo) = 0; + virtual int32_t NetworkSetDefault(int32_t netId) = 0; + virtual int32_t NetworkGetDefault() = 0; + virtual int32_t NetworkClearDefault() = 0; + virtual int32_t GetProcSysNet(int32_t family, int32_t which, const std::string &ifname, + const std::string ¶meter, std::string &value) = 0; + virtual int32_t SetProcSysNet(int32_t family, int32_t which, const std::string &ifname, + const std::string ¶meter, std::string &value) = 0; + virtual int32_t SetInternetPermission(uint32_t uid, uint8_t allow) = 0; + virtual int32_t NetworkCreatePhysical(int32_t netId, int32_t permission) = 0; + virtual int32_t NetworkCreateVirtual(int32_t netId, bool hasDns) = 0; + virtual int32_t NetworkAddUids(int32_t netId, const std::vector &uidRanges) = 0; + virtual int32_t NetworkDelUids(int32_t netId, const std::vector &uidRanges) = 0; + virtual int32_t AddInterfaceAddress(const std::string &interfaceName, const std::string &addrString, + int32_t prefixLength) = 0; + virtual int32_t DelInterfaceAddress(const std::string &interfaceName, const std::string &addrString, + int32_t prefixLength) = 0; + virtual int32_t InterfaceSetIpAddress(const std::string &ifaceName, const std::string &ipAddress) = 0; + virtual int32_t InterfaceSetIffUp(const std::string &ifaceName) = 0; + virtual int32_t NetworkAddInterface(int32_t netId, const std::string &iface) = 0; + virtual int32_t NetworkRemoveInterface(int32_t netId, const std::string &iface) = 0; + virtual int32_t NetworkDestroy(int32_t netId) = 0; + virtual int32_t GetFwmarkForNetwork(int32_t netId, MarkMaskParcel &markMaskParcel) = 0; + virtual int32_t SetInterfaceConfig(const InterfaceConfigurationParcel &cfg) = 0; + virtual int32_t GetInterfaceConfig(InterfaceConfigurationParcel &cfg) = 0; + virtual int32_t InterfaceGetList(std::vector &ifaces) = 0; + virtual int32_t StartDhcpClient(const std::string &iface, bool bIpv6) = 0; + virtual int32_t StopDhcpClient(const std::string &iface, bool bIpv6) = 0; + virtual int32_t StartDhcpService(const std::string &iface, const std::string &ipv4addr) = 0; + virtual int32_t StopDhcpService(const std::string &iface) = 0; + virtual int32_t IpEnableForwarding(const std::string &requestor) = 0; + virtual int32_t IpDisableForwarding(const std::string &requestor) = 0; + virtual int32_t EnableNat(const std::string &downstreamIface, const std::string &upstreamIface) = 0; + virtual int32_t DisableNat(const std::string &downstreamIface, const std::string &upstreamIface) = 0; + virtual int32_t IpfwdAddInterfaceForward(const std::string &fromIface, const std::string &toIface) = 0; + virtual int32_t IpfwdRemoveInterfaceForward(const std::string &fromIface, const std::string &toIface) = 0; + virtual int32_t BandwidthAddAllowedList(uint32_t uid) = 0; + virtual int32_t BandwidthRemoveAllowedList(uint32_t uid) = 0; + virtual int32_t BandwidthEnableDataSaver(bool enable) = 0; + virtual int32_t BandwidthSetIfaceQuota(const std::string &ifName, int64_t bytes) = 0; + virtual int32_t BandwidthAddDeniedList(uint32_t uid) = 0; + virtual int32_t BandwidthRemoveDeniedList(uint32_t uid) = 0; + virtual int32_t BandwidthRemoveIfaceQuota(const std::string &ifName) = 0; + virtual int32_t FirewallSetUidsAllowedListChain(uint32_t chain, const std::vector &uids) = 0; + virtual int32_t FirewallSetUidsDeniedListChain(uint32_t chain, const std::vector &uids) = 0; + virtual int32_t FirewallEnableChain(uint32_t chain, bool enable) = 0; + virtual int32_t FirewallSetUidRule(uint32_t chain, const std::vector &uids, uint32_t firewallRule) = 0; + virtual int32_t ShareDnsSet(uint16_t netId) = 0; + virtual int32_t StartDnsProxyListen() = 0; + virtual int32_t StopDnsProxyListen() = 0; + virtual int32_t GetNetworkSharingTraffic(const std::string &downIface, const std::string &upIface, + NetworkSharingTraffic &traffic) = 0; + virtual int32_t GetTotalStats(uint64_t &stats, uint32_t type) = 0; + virtual int32_t GetUidStats(uint64_t &stats, uint32_t type, uint32_t uid) = 0; + virtual int32_t GetIfaceStats(uint64_t &stats, uint32_t type, const std::string &interfaceName) = 0; + virtual int32_t GetAllStatsInfo(std::vector &stats) = 0; + virtual int32_t SetIptablesCommandForRes(const std::string &cmd, std::string &respond) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetsysNative.INetsysService") +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // I_NETSYS_SERVICE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_notify_callback.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_notify_callback.h new file mode 100644 index 00000000..5eca2bbb --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/i_notify_callback.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef I_NOTIFY_CALLBACK_H +#define I_NOTIFY_CALLBACK_H + +#include + +#include "dhcp_result_parcel.h" +#include "iremote_broker.h" +#include "netsys_ipc_interface_code.h" + +namespace OHOS { +namespace NetsysNative { +class INotifyCallback : public IRemoteBroker { +public: + virtual ~INotifyCallback() = default; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetsysNative.INotifyCallback"); + +public: + virtual int32_t OnInterfaceAddressUpdated(const std::string &addr, const std::string &ifName, int flags, + int scope) = 0; + virtual int32_t OnInterfaceAddressRemoved(const std::string &addr, const std::string &ifName, int flags, + int scope) = 0; + virtual int32_t OnInterfaceAdded(const std::string &ifName) = 0; + virtual int32_t OnInterfaceRemoved(const std::string &ifName) = 0; + virtual int32_t OnInterfaceChanged(const std::string &ifName, bool up) = 0; + virtual int32_t OnInterfaceLinkStateChanged(const std::string &ifName, bool up) = 0; + virtual int32_t OnRouteChanged(bool updated, const std::string &route, const std::string &gateway, + const std::string &ifName) = 0; + virtual int32_t OnDhcpSuccess(sptr &dhcpResult) = 0; + virtual int32_t OnBandwidthReachedLimit(const std::string &limitName, const std::string &iface) = 0; +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // I_NOTIFY_CALLBACK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/interface_type.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/interface_type.h new file mode 100644 index 00000000..b40931db --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/interface_type.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_INTERFACE_TYPE_H +#define INCLUDE_INTERFACE_TYPE_H + +#include +#include +#include + +namespace OHOS { +namespace nmd { +typedef struct InterfaceConfigurationParcel { + std::string ifName; + std::string hwAddr; + std::string ipv4Addr; + int prefixLength; + std::vector flags; + friend std::ostream &operator<<(std::ostream &os, const nmd::InterfaceConfigurationParcel &parcel) + { + os << "ifName: " << parcel.ifName << "\n" + << "hwAddr: " << parcel.hwAddr << "\n" + << "ipv4Addr: " << parcel.ipv4Addr << "\n" + << "prefixLength: " << parcel.prefixLength << "\n" + << "flags: [" + << "\n"; + for (unsigned long i = 0; i < parcel.flags.size(); i++) { + os << " " << parcel.flags[i] << "\n"; + } + os << "] " + << "\n"; + return os; + } +} InterfaceConfigurationParcel; +} // namespace nmd +} // namespace OHOS +#endif // INCLUDE_INTERFACE_TYPE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/iptables_type.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/iptables_type.h new file mode 100644 index 00000000..881d924f --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/iptables_type.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETMANAGER_BASE_IPTABLES_TYPE_H +#define NETMANAGER_BASE_IPTABLES_TYPE_H + +namespace OHOS { +namespace NetManagerStandard { +enum FirewallRule { + RULE_ALLOW = 1, + RULE_DENY = 2, +}; + +enum FirewallType { + TYPE_ALLOWED_LIST = 1, + TYPE_DENIDE_LIST = 2, +}; + +enum ChainType { + CHAIN_NONE = 0, + CHAIN_INPUT, + CHAIN_OUTPUT, + CHAIN_FORWARD, + CHAIN_OHBW_INPUT, + CHAIN_OHBW_OUTPUT, + CHAIN_OHBW_FORWARD, + CHAIN_OHFW_INPUT, + CHAIN_OHFW_OUTPUT, + CHAIN_OHFW_FORWARD, + CHAIN_OHTC_FORWARD, + CHAIN_OHBW_GLOBAL_ALERT, + CHAIN_OHBW_COSTLY_SHARED, + CHAIN_OHBW_DENIED_LIST_BOX, + CHAIN_OHBW_ALLOWED_LIST_BOX, + CHAIN_OHBW_DATA_SAVER, + CHAIN_OHFW_DOZABLE, + CHAIN_OHFW_POWERSAVING, + CHAIN_OHFW_UNDOZABLE, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif /* NETMANAGER_BASE_IPTABLES_TYPE_H */ diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netnative_log_wrapper.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netnative_log_wrapper.h new file mode 100644 index 00000000..b989a17f --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netnative_log_wrapper.h @@ -0,0 +1,41 @@ +/* + * 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 NETNATIVE_LOG_WRAPPER_H +#define NETNATIVE_LOG_WRAPPER_H + +#include +#include +#include "hilog/log.h" + +#ifndef NETMGRNATIVE_LOG_TAG +#define NETMGRNATIVE_LOG_TAG "NetsysNativeService" +#endif + +static constexpr OHOS::HiviewDFX::HiLogLabel NET_MGR_LABEL = {LOG_CORE, LOG_DOMAIN, NETMGRNATIVE_LOG_TAG}; + +#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define PRINT_NATIVE_LOG(op, fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::op(NET_MGR_LABEL, "[%{public}s-(%{public}s:%{public}d)]" fmt, __FUNCTION__, \ + FILENAME, __LINE__, ##__VA_ARGS__) + +#define NETNATIVE_LOG_D(fmt, ...) PRINT_NATIVE_LOG(Debug, fmt, ##__VA_ARGS__) +#define NETNATIVE_LOGE(fmt, ...) PRINT_NATIVE_LOG(Error, fmt, ##__VA_ARGS__) +#define NETNATIVE_LOGW(fmt, ...) PRINT_NATIVE_LOG(Warn, fmt, ##__VA_ARGS__) +#define NETNATIVE_LOGI(fmt, ...) PRINT_NATIVE_LOG(Info, fmt, ##__VA_ARGS__) +#define NETNATIVE_LOGF(fmt, ...) PRINT_NATIVE_LOG(Fatal, fmt, ##__VA_ARGS__) + +#endif // NETNATIVE_LOG_WRAPPER_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_addr_info_parcel.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_addr_info_parcel.h new file mode 100644 index 00000000..a93498c5 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_addr_info_parcel.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETSYS_ADDR_INFO_H +#define NETSYS_ADDR_INFO_H + +#include +#include +#include + +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace NetsysNative { +struct NetsysAddrInfoParcel final : public Parcelable { +public: + NetsysAddrInfoParcel() = default; + NetsysAddrInfoParcel(const addrinfo *addr, const uint16_t netId, const std::string Node, + const std::string ServData); + ~NetsysAddrInfoParcel() = default; + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(MessageParcel &parcel); + static bool UnmarshallingAddrinfo(MessageParcel &parcelMsg, int size, addrinfo *headNode); + + addrinfo *addrHead; + int32_t aiFamily; + int32_t aiSocktype; + int32_t aiFlags; + int32_t aiProtocol; + int32_t aiAddrlen; + int32_t netId; + int32_t ret; + int32_t addrSize; + int32_t isHintsNull; + std::string hostName; + std::string serverName; +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // NETSYS_ADDR_INFO_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_ipc_interface_code.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_ipc_interface_code.h new file mode 100644 index 00000000..a57bab59 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_ipc_interface_code.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETSYS_IPC_INTERFACE_CODE_H +#define NETSYS_IPC_INTERFACE_CODE_H + +/* SAID: 1158 */ +namespace OHOS { +namespace NetsysNative { +enum class NetsysInterfaceCode { + NETSYS_SET_RESOLVER_CONFIG_PARCEL, + NETSYS_SET_RESOLVER_CONFIG, + NETSYS_GET_RESOLVER_CONFIG, + NETSYS_CREATE_NETWORK_CACHE, + NETSYS_FLUSH_NETWORK_CACHE, + NETSYS_DESTROY_NETWORK_CACHE, + NETSYS_GET_ADDR_INFO, + NETSYS_INTERFACE_SET_MTU, + NETSYS_INTERFACE_GET_MTU, + NETSYS_REGISTER_NOTIFY_CALLBACK, + NETSYS_UNREGISTER_NOTIFY_CALLBACK, + NETSYS_NETWORK_ADD_ROUTE, + NETSYS_NETWORK_REMOVE_ROUTE, + NETSYS_NETWORK_ADD_ROUTE_PARCEL, + NETSYS_NETWORK_REMOVE_ROUTE_PARCEL, + NETSYS_NETWORK_SET_DEFAULT, + NETSYS_NETWORK_GET_DEFAULT, + NETSYS_NETWORK_CLEAR_DEFAULT, + NETSYS_GET_PROC_SYS_NET, + NETSYS_SET_PROC_SYS_NET, + NETSYS_NETWORK_CREATE_PHYSICAL, + NETSYS_INTERFACE_ADD_ADDRESS, + NETSYS_INTERFACE_DEL_ADDRESS, + NETSYS_INTERFACE_SET_IP_ADDRESS, + NETSYS_INTERFACE_SET_IFF_UP, + NETSYS_NETWORK_ADD_INTERFACE, + NETSYS_NETWORK_REMOVE_INTERFACE, + NETSYS_NETWORK_DESTROY, + NETSYS_GET_FWMARK_FOR_NETWORK, + NETSYS_INTERFACE_SET_CONFIG, + NETSYS_INTERFACE_GET_CONFIG, + NETSYS_INTERFACE_GET_LIST, + NETSYS_START_DHCP_CLIENT, + NETSYS_STOP_DHCP_CLIENT, + NETSYS_START_DHCP_SERVICE, + NETSYS_STOP_DHCP_SERVICE, + NETSYS_IPENABLE_FORWARDING, + NETSYS_IPDISABLE_FORWARDING, + NETSYS_ENABLE_NAT, + NETSYS_DISABLE_NAT, + NETSYS_IPFWD_ADD_INTERFACE_FORWARD, + NETSYS_IPFWD_REMOVE_INTERFACE_FORWARD, + NETSYS_BANDWIDTH_ENABLE_DATA_SAVER, + NETSYS_BANDWIDTH_SET_IFACE_QUOTA, + NETSYS_BANDWIDTH_REMOVE_IFACE_QUOTA, + NETSYS_BANDWIDTH_ADD_DENIED_LIST, + NETSYS_BANDWIDTH_REMOVE_DENIED_LIST, + NETSYS_BANDWIDTH_ADD_ALLOWED_LIST, + NETSYS_BANDWIDTH_REMOVE_ALLOWED_LIST, + NETSYS_FIREWALL_SET_UID_ALLOWED_LIST_CHAIN, + NETSYS_FIREWALL_SET_UID_DENIED_LIST_CHAIN, + NETSYS_FIREWALL_ENABLE_CHAIN, + NETSYS_FIREWALL_SET_UID_RULE, + NETSYS_TETHER_DNS_SET, + NETSYS_START_DNS_PROXY_LISTEN, + NETSYS_STOP_DNS_PROXY_LISTEN, + NETSYS_GET_SHARING_NETWORK_TRAFFIC, + NETSYS_GET_TOTAL_STATS, + NETSYS_GET_UID_STATS, + NETSYS_GET_IFACE_STATS, + NETSYS_GET_ALL_STATS_INFO, + NETSYS_DISALLOW_INTERNET, + NETSYS_SET_IPTABLES_CMD_FOR_RES, + NETSYS_SET_INTERNET_PERMISSION, + NETSYS_NETWORK_CREATE_VIRTUAL, + NETSYS_NETWORK_ADD_UIDS, + NETSYS_NETWORK_DEL_UIDS, +}; + +enum class NotifyInterfaceCode { + ON_INTERFACE_ADDRESS_UPDATED = 0, + ON_INTERFACE_ADDRESS_REMOVED, + ON_INTERFACE_ADDED, + ON_INTERFACE_REMOVED, + ON_INTERFACE_CHANGED, + ON_INTERFACE_LINK_STATE_CHANGED, + ON_ROUTE_CHANGED, + ON_DHCP_SUCCESS, + ON_BANDWIDTH_REACHED_LIMIT, +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // NETSYS_IPC_INTERFACE_CODE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_native_service_proxy.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_native_service_proxy.h new file mode 100644 index 00000000..3fc37ace --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/netsys_native_service_proxy.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETSYS_NATIVE_SERVICE_PROXY_H +#define NETSYS_NATIVE_SERVICE_PROXY_H + +#include "i_netsys_service.h" +#include "iremote_proxy.h" + +#define NET_SYMBOL_VISIBLE __attribute__ ((visibility("default"))) +namespace OHOS { +namespace NetsysNative { +class NET_SYMBOL_VISIBLE NetsysNativeServiceProxy : public IRemoteProxy { +public: + explicit NetsysNativeServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} + ~NetsysNativeServiceProxy() override {} + bool WriteInterfaceToken(MessageParcel &data); + int32_t SetResolverConfig(uint16_t netId, uint16_t baseTimeoutMsec, uint8_t retryCount, + const std::vector &servers, + const std::vector &domains) override; + int32_t GetResolverConfig(uint16_t netId, std::vector &servers, std::vector &domains, + uint16_t &baseTimeoutMsec, uint8_t &retryCount) override; + int32_t CreateNetworkCache(uint16_t netId) override; + int32_t DestroyNetworkCache(uint16_t netId) override; + int32_t GetAddrInfo(const std::string &hostName, const std::string &serverName, const AddrInfo &hints, + uint16_t netId, std::vector &res) override; + int32_t SetInterfaceMtu(const std::string &interfaceName, int32_t mtu) override; + int32_t GetInterfaceMtu(const std::string &interfaceName) override; + + int32_t RegisterNotifyCallback(sptr &callback) override; + int32_t UnRegisterNotifyCallback(sptr &callback) override; + + int32_t NetworkAddRoute(int32_t netId, const std::string &interfaceName, const std::string &destination, + const std::string &nextHop) override; + int32_t NetworkRemoveRoute(int32_t netId, const std::string &interfaceName, const std::string &destination, + const std::string &nextHop) override; + int32_t NetworkAddRouteParcel(int32_t netId, const RouteInfoParcel &routeInfo) override; + int32_t NetworkRemoveRouteParcel(int32_t netId, const RouteInfoParcel &routeInfo) override; + int32_t NetworkSetDefault(int32_t netId) override; + int32_t NetworkGetDefault() override; + int32_t NetworkClearDefault() override; + int32_t GetProcSysNet(int32_t family, int32_t which, const std::string &ifname, const std::string ¶meter, + std::string &value) override; + int32_t SetProcSysNet(int32_t family, int32_t which, const std::string &ifname, const std::string ¶meter, + std::string &value) override; + int32_t SetInternetPermission(uint32_t uid, uint8_t allow) override; + int32_t NetworkCreatePhysical(int32_t netId, int32_t permission) override; + int32_t NetworkCreateVirtual(int32_t netId, bool hasDns) override; + int32_t NetworkAddUids(int32_t netId, const std::vector &uidRanges) override; + int32_t NetworkDelUids(int32_t netId, const std::vector &uidRanges) override; + int32_t AddInterfaceAddress(const std::string &interfaceName, const std::string &addrString, + int32_t prefixLength) override; + int32_t DelInterfaceAddress(const std::string &interfaceName, const std::string &addrString, + int32_t prefixLength) override; + int32_t InterfaceSetIpAddress(const std::string &ifaceName, const std::string &ipAddress) override; + int32_t InterfaceSetIffUp(const std::string &ifaceName) override; + int32_t NetworkAddInterface(int32_t netId, const std::string &iface) override; + int32_t NetworkRemoveInterface(int32_t netId, const std::string &iface) override; + int32_t NetworkDestroy(int32_t netId) override; + int32_t GetFwmarkForNetwork(int32_t netId, MarkMaskParcel &markMaskParcel) override; + int32_t SetInterfaceConfig(const InterfaceConfigurationParcel &cfg) override; + int32_t GetInterfaceConfig(InterfaceConfigurationParcel &cfg) override; + int32_t StartDhcpClient(const std::string &iface, bool bIpv6) override; + int32_t InterfaceGetList(std::vector &ifaces) override; + int32_t StopDhcpClient(const std::string &iface, bool bIpv6) override; + int32_t StartDhcpService(const std::string &iface, const std::string &ipv4addr) override; + int32_t StopDhcpService(const std::string &iface) override; + int32_t IpEnableForwarding(const std::string &requestor) override; + int32_t IpDisableForwarding(const std::string &requestor) override; + int32_t EnableNat(const std::string &downstreamIface, const std::string &upstreamIface) override; + int32_t DisableNat(const std::string &downstreamIface, const std::string &upstreamIface) override; + int32_t IpfwdAddInterfaceForward(const std::string &fromIface, const std::string &toIface) override; + int32_t IpfwdRemoveInterfaceForward(const std::string &fromIface, const std::string &toIface) override; + int32_t FirewallEnableChain(uint32_t chain, bool enable) override; + int32_t FirewallSetUidRule(uint32_t chain, const std::vector &uids, uint32_t firewallRule) override; + int32_t BandwidthRemoveAllowedList(uint32_t uid) override; + int32_t FirewallSetUidsAllowedListChain(uint32_t chain, const std::vector &uids) override; + int32_t FirewallSetUidsDeniedListChain(uint32_t chain, const std::vector &uids) override; + int32_t BandwidthRemoveIfaceQuota(const std::string &ifName) override; + int32_t BandwidthRemoveDeniedList(uint32_t uid) override; + int32_t BandwidthAddDeniedList(uint32_t uid) override; + int32_t BandwidthAddAllowedList(uint32_t uid) override; + int32_t BandwidthEnableDataSaver(bool enable) override; + int32_t BandwidthSetIfaceQuota(const std::string &ifName, int64_t bytes) override; + int32_t ShareDnsSet(uint16_t netId) override; + int32_t StartDnsProxyListen() override; + int32_t StopDnsProxyListen() override; + int32_t GetNetworkSharingTraffic(const std::string &downIface, const std::string &upIface, + NetworkSharingTraffic &traffic) override; + int32_t GetTotalStats(uint64_t &stats, uint32_t type) override; + int32_t GetUidStats(uint64_t &stats, uint32_t type, uint32_t uid) override; + int32_t GetIfaceStats(uint64_t &stats, uint32_t type, const std::string &interfaceName) override; + int32_t GetAllStatsInfo(std::vector &stats) override; + int32_t SetIptablesCommandForRes(const std::string &cmd, std::string &respond) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // NETSYS_NATIVE_SERVICE_PROXY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_permission.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_permission.h new file mode 100644 index 00000000..64b10f63 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_permission.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_NETWORK_PERMISSION_H +#define INCLUDE_NETWORK_PERMISSION_H + +namespace OHOS { +namespace nmd { +enum NetworkPermission : int32_t { + PERMISSION_NONE = 0x0, + PERMISSION_NETWORK = 0x1, + PERMISSION_SYSTEM = 0x3, +}; +} // namespace nmd +} // namespace OHOS +#endif // INCLUDE_NETWORK_PERMISSION_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_sharing.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_sharing.h new file mode 100644 index 00000000..4e11bb0f --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/network_sharing.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETWORK_SHARING_H +#define NETWORK_SHARING_H + +namespace OHOS { +namespace nmd { +struct NetworkSharingTraffic { + int64_t receive = 0; + int64_t send = 0; + int64_t all = 0; +}; +} // namespace nmd +} // namespace OHOS + +#endif // NETWORK_SHARING_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_proxy.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_proxy.h new file mode 100644 index 00000000..097bf56e --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_proxy.h @@ -0,0 +1,45 @@ +/* + * 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 NOTIFY_CALLBACK_PROXY_H +#define NOTIFY_CALLBACK_PROXY_H +#include "iremote_proxy.h" + +#include "i_notify_callback.h" + +namespace OHOS { +namespace NetsysNative { +class NotifyCallbackProxy : public IRemoteProxy { +public: + explicit NotifyCallbackProxy(const sptr &impl); + virtual ~NotifyCallbackProxy(); + int32_t OnInterfaceAddressUpdated(const std::string &addr, const std::string &ifName, int flags, + int scope) override; + int32_t OnInterfaceAddressRemoved(const std::string &addr, const std::string &ifName, int flags, + int scope) override; + int32_t OnInterfaceAdded(const std::string &ifName) override; + int32_t OnInterfaceRemoved(const std::string &ifName) override; + int32_t OnInterfaceChanged(const std::string &ifName, bool up) override; + int32_t OnInterfaceLinkStateChanged(const std::string &ifName, bool up) override; + int32_t OnRouteChanged(bool updated, const std::string &route, const std::string &gateway, + const std::string &ifName) override; + int32_t OnDhcpSuccess(sptr &dhcpResult) override; + int32_t OnBandwidthReachedLimit(const std::string &limitName, const std::string &iface) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // NOTIFY_CALLBACK_PROXY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_stub.h new file mode 100644 index 00000000..b6e359f7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/notify_callback_stub.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef NOTIFY_CALLBACK_STUB_H +#define NOTIFY_CALLBACK_STUB_H +#include + +#include "iremote_stub.h" + +#include "i_notify_callback.h" + +#define NET_SYMBOL_VISIBLE __attribute__ ((visibility("default"))) +namespace OHOS { +namespace NetsysNative { +class NET_SYMBOL_VISIBLE NotifyCallbackStub : public IRemoteStub { +public: + NotifyCallbackStub(); + virtual ~NotifyCallbackStub(); + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using NotifyCallbackFunc = int32_t (NotifyCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t CmdOnInterfaceAddressUpdated(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnInterfaceAddressRemoved(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnInterfaceAdded(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnInterfaceRemoved(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnInterfaceChanged(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnInterfaceLinkStateChanged(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnRouteChanged(MessageParcel &data, MessageParcel &reply); + int32_t CmdDhcpSuccess(MessageParcel &data, MessageParcel &reply); + int32_t CmdOnBandwidthReachedLimit(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetsysNative +} // namespace OHOS +#endif // NOTIFY_CALLBACK_STUB_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/route_type.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/route_type.h new file mode 100644 index 00000000..c39aead7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/route_type.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_ROUTE_TYPE_H +#define INCLUDE_ROUTE_TYPE_H + +#include + +namespace OHOS { +namespace nmd { +static const int LOCAL_NETWORK_NETID = 99; + +typedef struct RouteInfoParcel { + std::string destination; + std::string ifName; + std::string nextHop; + int mtu; +} RouteInfoParcel; + +typedef struct MarkMaskParcel { + int mark; + int mask; +} MarkMaskParcel; +} // namespace nmd +} // namespace OHOS +#endif // INCLUDE_ROUTE_TYPE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/uid_range.h b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/uid_range.h new file mode 100644 index 00000000..e06c8c1c --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netmanagernative/include/uid_range.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_UID_RANGE_H +#define APP_UID_RANGE_H + +#include + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +struct __attribute__ ((visibility("default"))) UidRange : public Parcelable { + UidRange(int32_t begin, int32_t end); + UidRange() = default; + virtual ~UidRange(){}; + + uint32_t Size() const; + + friend bool operator<(const UidRange &lhs, const UidRange &rhs) + { + return lhs.begin_ != rhs.begin_ ? (lhs.begin_ < rhs.begin_) : (lhs.end_ < rhs.end_); + } + + friend bool operator==(const UidRange &lhs, const UidRange &rhs) + { + return (lhs.begin_ == rhs.begin_ && lhs.end_ == rhs.end_); + } + + friend bool operator!=(const UidRange &lhs, const UidRange &rhs) + { + return !(lhs == rhs); + } + + bool Marshalling(Parcel &parcel) const override; + static sptr Unmarshalling(Parcel &parcel); + + int32_t begin_ = -1; + int32_t end_ = -1; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // APP_UID_RANGE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/BUILD.gn b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/BUILD.gn new file mode 100644 index 00000000..512a68e1 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/BUILD.gn @@ -0,0 +1,102 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/netmanager_base/netmanager_base_config.gni") + +config("net_policy_manager_if_config") { + # header file path + include_dirs = [ + "$INNERKITS_ROOT/include", + "$INNERKITS_ROOT/netpolicyclient/include", + "$INNERKITS_ROOT/netpolicyclient/include/proxy", + "$INNERKITS_ROOT/netconnclient/include", + "$NETSYSNATIVE_SOURCE_DIR/include/netsys", + ] + + cflags = [] + if (is_double_framework) { + cflags += [ "-DCONFIG_DUAL_FRAMEWORK" ] + } + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + if (is_standard_system) { + cflags += [ "-DCONFIG_STANDARD_SYSTEM" ] + } + if (defined(build_public_version) && build_public_version) { + cflags += [ "-DBUILD_PUBLIC_VERSION" ] + } +} + +ohos_source_set("net_policy_parcel") { + sources = + [ "$NETPOLICYMANAGER_INNERKITS_SOURCE_DIR/src/net_quota_policy.cpp" ] + + include_dirs = [ + "$INNERKITS_ROOT/include", + "$INNERKITS_ROOT/netpolicyclient/include", + "$INNERKITS_ROOT/netconnclient/include", + "$NETMANAGER_BASE_ROOT/utils/log/include", + ] + + deps = [ "$NETMANAGER_BASE_ROOT/utils:net_manager_common" ] + + external_deps = [ "c_utils:utils" ] + external_deps += [ "hilog:libhilog" ] + + part_name = "netmanager_base" + subsystem_name = "communication" +} + +ohos_shared_library("net_policy_manager_if") { + sanitize = { + integer_overflow = true + boundary_sanitize = true + all_ubsan = true + } + + include_dirs = [ "$NETMANAGER_BASE_ROOT/utils/log/include" ] + + sources = [ + "$NETPOLICYMANAGER_INNERKITS_SOURCE_DIR/src/net_policy_client.cpp", + "$NETPOLICYMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_policy_callback_stub.cpp", + "$NETPOLICYMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_policy_service_proxy.cpp", + ] + + version_script = "libnetpolicy_kits.map" + + public_configs = [ ":net_policy_manager_if_config" ] + + deps = [ ":net_policy_parcel" ] + + external_deps = [ + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + defines = [ + "NETMGR_LOG_TAG = \"NetPolicyManager\"", + "LOG_DOMAIN = 0xD0015B0", + ] + + if (enable_netmgr_debug) { + defines += [ "NETMGR_DEBUG" ] + } + + external_deps += [ "hilog:libhilog" ] + + innerapi_tags = [ "platformsdk" ] + part_name = "netmanager_base" + subsystem_name = "communication" +} diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_client.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_client.h new file mode 100644 index 00000000..34c790c7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_client.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_POLICY_CLIENT_H +#define NET_POLICY_CLIENT_H + +#include + +#include "singleton.h" + +#include "i_net_policy_service.h" +#include "net_policy_constants.h" +#include "net_quota_policy.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetPolicyClient : public Singleton { +public: + NetPolicyClient(); + ~NetPolicyClient(); + + /** + * Set the network policy for the specified UID. + * + * @param uid The specified UID of app. + * @param policy The network policy for application, for details, see {@link NetUidPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetPolicyByUid(uint32_t uid, uint32_t policy); + + /** + * Get the network policy of the specified UID. + * + * @param uid The specified UID of app. + * @param policy The network policy of the specified UID application, for details, see {@link NetUidPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetPolicyByUid(uint32_t uid, uint32_t &policy); + + /** + * Get the application UIDs of the specified policy. + * + * @param policy the network policy of the current UID of application, for details, see {@link NetUidPolicy}. + * @param uids put the result into uids + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetUidsByPolicy(uint32_t policy, std::vector &uids); + + /** + * Get the status whether the specified uid app can access the metered network or non-metered network. + * + * @param uid The specified UID of application. + * @param metered Indicates meterd network or non-metered network. + * @param isAllowed Put the result into "isAllowed". + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t IsUidNetAllowed(uint32_t uid, bool metered, bool &isAllowed); + + /** + * Get the status whether the specified uid app can access the specified iface network. + * + * @param uid The specified UID of application. + * @param ifaceName Iface name. + * @param isAllowed Put the result into "isAllowed". + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t IsUidNetAllowed(uint32_t uid, const std::string &ifaceName, bool &isAllowed); + + /** + * @deprecated + */ + [[nodiscard]] int32_t IsUidNetAccess(uint32_t uid, bool isMetered, bool &isAllowed); + + /** + * @deprecated + */ + [[nodiscard]] int32_t IsUidNetAccess(uint32_t uid, const std::string &ifaceName, bool &isAllowed); + + /** + * Register network policy change callback. + * + * @param callback The callback of INetPolicyCallback interface. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t RegisterNetPolicyCallback(const sptr &callback); + + /** + * Unregister network policy change callback. + * + * @param callback The callback of INetPolicyCallback interface. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t UnregisterNetPolicyCallback(const sptr &callback); + + /** + * Set network policies. + * + * @param quotaPolicies The list of network quota policy, {@link NetQuotaPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetNetQuotaPolicies(const std::vector "aPolicies); + + /** + * Get network policies. + * + * @param quotaPolicies The list of network quota policy, {@link NetQuotaPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetNetQuotaPolicies(std::vector "aPolicies); + + /** + * SetFactoryPolicy reset policys for simId. + * + * @param simId ID, get from telephone module + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + * @deprecated + */ + NetPolicyResultCode SetFactoryPolicy(const std::string &simId); + + /** + * Reset network policies\rules\quota policies\firewall rules. + * + * @param simId Specify the matched simId of quota policy. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t ResetPolicies(const std::string &simId); + + /** + * Control if apps can use data on background. + * + * @param isAllowed Allow apps to use data on background or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetBackgroundPolicy(bool isAllowed); + + /** + * Get the status if apps can use data on background. + * + * @param backgroundPolicy Put the background policy's value + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetBackgroundPolicy(bool &backgroundPolicy); + + /** + * Get the background network restriction policy for the specified uid. + * + * @param uid The specified UID of application. + * @param backgroundPolicyOfUid The result of this uid's background policy,{@link NetBackgroundPolicy} + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetBackgroundPolicyByUid(uint32_t uid, uint32_t &backgroundPolicyOfUid); + + /** + * SetSnoozePolicy for Hibernate current policy + * + * @param netType {@link NetBearType}. + * @param simId Specify the matched simId of quota policy when netType is cellular. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + * @deprecated + */ + NetPolicyResultCode SetSnoozePolicy(int8_t netType, const std::string &simId); + + /** + * Update the limit or warning remind time of quota policy. + * + * @param netType {@link NetBearType}. + * @param simId Specify the matched simId of quota policy when netType is cellular. + * @param remindType {@link RemindType}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t UpdateRemindPolicy(int32_t netType, const std::string &simId, uint32_t remindType); + + /** + * SetIdleTrustlist for add trust list for Idle status + * + * @param uid uid + * @param isTrustlist true/false + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + * @deprecated + */ + NetPolicyResultCode SetIdleTrustlist(uint32_t uid, bool isTrustlist); + + /** + * Set the UID into device idle allow list. + * + * @param uid The specified UID of application. + * @param isAllowed The UID is into allow list or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetDeviceIdleTrustlist(const std::vector &uid, bool isAllowed); + + /** + * GetIdleTrustlist for get trust list for Idle status + * + * @param uids The uids are into into allow list + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + * @deprecated + */ + NetPolicyResultCode GetIdleTrustlist(std::vector &uids); + + /** + * Get the allow list of UID in device idle mode. + * + * @param uids The list of UIDs + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetDeviceIdleTrustlist(std::vector &uids); + + /** + * Process network policy in device idle mode. + * + * @param enable Device idle mode is open or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t SetDeviceIdlePolicy(bool enable); + + /** + * Get the allow list of UID in power save mode. + * + * @param uids The list of UIDs + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t GetPowerSaveTrustlist(std::vector &uids); + + /** + * Get the allow list of UID in power save mode. + * + * @param uid The list of UIDs + * @param isAllowed The UID is into allow list or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetPowerSaveTrustlist(const std::vector &uid, bool isAllowed); + + /** + * Set the Power Save Policy object + * + * @param enable Power save mode is open or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + [[nodiscard]] int32_t SetPowerSavePolicy(bool enable); + + /** + * Check if you have permission + * + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + [[nodiscard]] int32_t CheckPermission(); + +private: + class NetPolicyDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit NetPolicyDeathRecipient(NetPolicyClient &client) : client_(client) {} + ~NetPolicyDeathRecipient() override = default; + void OnRemoteDied(const wptr &remote) override + { + client_.OnRemoteDied(remote); + } + + private: + NetPolicyClient &client_; + }; + +private: + sptr GetProxy(); + void OnRemoteDied(const wptr &remote); + +private: + std::mutex mutex_; + sptr netPolicyService_; + sptr deathRecipient_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_POLICY_CLIENT_H diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_constants.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_constants.h new file mode 100644 index 00000000..7ed30cdf --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_policy_constants.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_POLICY_CONSTANTS_H +#define NET_POLICY_CONSTANTS_H + +#include + +#include "net_manager_constants.h" + +namespace OHOS { +namespace NetManagerStandard { +static constexpr int64_t DATA_USAGE_UNKNOWN = -1; +static constexpr int64_t DATA_USAGE_UNLIMITED = LONG_MAX; +static constexpr int64_t REMIND_NEVER = -1; +constexpr const char *QUOTA_POLICY_NO_PERIOD = "--"; + +enum NetPolicyResultCode { + POLICY_ERR_INVALID_UID = 2104002, + POLICY_ERR_INVALID_POLICY = 2104003, + POLICY_ERR_INVALID_QUOTA_POLICY = 2104004, + POLICY_ERR_QUOTA_POLICY_NOT_EXIST = 2104005, +}; + +enum NetUidPolicy { + /* Default net policy. */ + NET_POLICY_NONE = 0, + /* Reject on metered networks when app in background. */ + NET_POLICY_ALLOW_METERED_BACKGROUND = 1 << 0, + /* Allow on metered networks when app in background. */ + NET_POLICY_REJECT_METERED_BACKGROUND = 1 << 1, +}; + +enum NetUidRule { + /* Default uid rule */ + NET_RULE_NONE = 0, + /* Allow traffic on metered networks while app is foreground. */ + NET_RULE_ALLOW_METERED_FOREGROUND = 1 << 0, + /* Allow traffic on metered network. */ + NET_RULE_ALLOW_METERED = 1 << 1, + /* Reject traffic on metered network. */ + NET_RULE_REJECT_METERED = 1 << 2, + /* Allow traffic on all network (metered or non-metered). */ + NET_RULE_ALLOW_ALL = 1 << 5, + /* Reject traffic on all network. */ + NET_RULE_REJECT_ALL = 1 << 6, +}; + +enum NetBackgroundPolicy { + /* Default value. */ + NET_BACKGROUND_POLICY_NONE = 0, + /* Apps can use metered networks on background. */ + NET_BACKGROUND_POLICY_ENABLE = 1, + /* Apps can't use metered networks on background. */ + NET_BACKGROUND_POLICY_DISABLE = 2, + /* Only apps in allowedlist can use metered networks on background. */ + NET_BACKGROUND_POLICY_TRUSTLIST = 3, +}; + +enum PolicyTransCondition { + POLICY_TRANS_CONDITION_UID_POLICY_NONE = 1 << 0, + POLICY_TRANS_CONDITION_ALLOW_METERED_BACKGROUND = 1 << 1, + POLICY_TRANS_CONDITION_REJECT_METERED_BACKGROUND = 1 << 2, + POLICY_TRANS_CONDITION_FOREGROUND = 1 << 3, + POLICY_TRANS_CONDITION_BACKGROUND_RESTRICT = 1 << 4, + POLICY_TRANS_CONDITION_IDLE_ALLOWEDLIST = 1 << 5, + POLICY_TRANS_CONDITION_IDLE_MODE = 1 << 6, + POLICY_TRANS_CONDITION_POWERSAVE_ALLOWEDLIST = 1 << 7, + POLICY_TRANS_CONDITION_POWERSAVE_MODE = 1 << 8, + POLICY_TRANS_CONDITION_ADMIN_RESTRICT = 1 << 9, +}; + +enum LimitAction { + /* Default action, do nothing. */ + LIMIT_ACTION_NONE = -1, + /* Access is disabled, when quota policy hit the limit */ + LIMIT_ACTION_ACCESS_DISABLED = 0, + /* The user is billed automatically, when quota policy hit the limit */ + LIMIT_ACTION_ALERT_ONLY = 1, +}; + +enum RemindType { + /* Warning remind. */ + REMIND_TYPE_WARNING = 1, + /* Limit remind. */ + REMIND_TYPE_LIMIT = 2, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_POLICY_CONSTANTS_H diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_quota_policy.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_quota_policy.h new file mode 100644 index 00000000..5324fb2a --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/net_quota_policy.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_POLICY_QUOTA_POLICY_H +#define NET_POLICY_QUOTA_POLICY_H + +#include + +#include "parcel.h" + +#include "net_all_capabilities.h" +#include "net_policy_constants.h" + +namespace OHOS { +namespace NetManagerStandard { +static constexpr const char *PERIOD_DAY = "D"; +static constexpr const char *PERIOD_MONTH = "M"; +static constexpr const char *PERIOD_YEAR = "Y"; +static constexpr int32_t PERIOD_START = 1; +static constexpr int32_t DAY_MAX = 31; +static constexpr int32_t MONTH_MAX = 12; +static constexpr int32_t YEAR_MAX = 366; +static constexpr int32_t PERIOD_DURATION_SIZE = 2; +static constexpr int32_t QUOTA_POLICY_MAX_SIZE = 100; + +struct NetQuotaPolicy final: public Parcelable { + struct NetLogotype { + /* See {@link NetBearType} */ + int32_t netType = BEARER_DEFAULT; + /* The ID of the target card, valid when netType is BEARER_CELLULAR */ + std::string simId; + /* To specify the identity of network, such as different WLAN */ + std::string ident; + } networkmatchrule; + struct QuotaPolicy { + // @deprecated + int64_t periodStartTime = -1; + /* The period and the start time for quota policy, default: "M1" */ + std::string periodDuration = (PERIOD_MONTH + std::to_string(PERIOD_START)); + // @deprecated + std::string title; + // @deprecated + std::string summary; + /* The warning threshold of traffic, default: DATA_USAGE_UNKNOWN */ + int64_t warningBytes = DATA_USAGE_UNKNOWN; + /* The limit threshold of traffic, default: DATA_USAGE_UNKNOWN */ + int64_t limitBytes = DATA_USAGE_UNKNOWN; + /* The updated wall time that last warning remind, default: REMIND_NEVER */ + int64_t lastWarningRemind = REMIND_NEVER; + /* The updated wall time that last limit remind, default: REMIND_NEVER */ + int64_t lastLimitRemind = REMIND_NEVER; + /* Is metered network or not */ + bool metered = false; + // @deprecated + int32_t source = -1; + /* The action while the used bytes reach the limit, see {@link LimitAction} */ + int32_t limitAction = LimitAction::LIMIT_ACTION_NONE; + // @deprecated + int64_t usedBytes = -1; + // @deprecated + int64_t usedTimeDuration = -1; + // @deprecated + std::string possessor; + } quotapolicy; + + bool Marshalling(Parcel &parcel) const override; + static bool Marshalling(Parcel &parcel, const NetQuotaPolicy "aPolicy); + static bool Marshalling(Parcel &parcel, const std::vector "aPolicies); + static bool Unmarshalling(Parcel &parcel, NetQuotaPolicy "aPolicy); + static bool Unmarshalling(Parcel &parcel, std::vector "aPolicies); + /** + * Get the period start, transform the periodDuration to wall time. + * + * @return int64_t The wall time.of the period start. + */ + int64_t GetPeriodStart(); + + /** + * To judge the quota is over the warning threshold. + * + * @param totalQuota The total quota used. + * @return true Over the warning threshold. + * @return false + */ + bool IsOverWarning(int64_t totalQuota) const; + + /** + * To judge the quota is over the limit threshold. + * + * @param totalQuota The total quota used. + * @return true Over the limit threshold. + * @return false Not over. + */ + bool IsOverLimit(int64_t totalQuota) const; + + /** + * Reset the quota policy to default. + * + */ + void Reset(); +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_POLICY_QUOTA_POLICY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_callback.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_callback.h new file mode 100644 index 00000000..964b101c --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_callback.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_POLICY_CALLBACK_H +#define I_NET_POLICY_CALLBACK_H + +#include + +#include "iremote_broker.h" + +#include "net_policy_constants.h" +#include "net_quota_policy.h" +#include "policy_ipc_interface_code.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetPolicyCallback : public IRemoteBroker { +public: + virtual ~INetPolicyCallback() = default; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetPolicyCallback"); + +public: + /** + * Notify the net uid policy change + * + * @param uid The specified UID of app. + * @param policy The network policy for application. + * For details, see {@link NetUidPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t NetUidPolicyChange(uint32_t uid, uint32_t policy) = 0; + + /** + * Notify the net uid rule change + * + * @param uid The specified UID of app. + * @param rule The network rule for application. + * For details, see {@link NetUidRule}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t NetUidRuleChange(uint32_t uid, uint32_t rule) = 0; + + /** + * Notify the quota policy change + * + * @param quotaPolicies The list of network quota policy, {@link NetQuotaPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t NetQuotaPolicyChange(const std::vector "aPolicies) = 0; + + /** + * Notify the metered ifaces change + * + * @param ifaces The vector of metered ifaces + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t NetMeteredIfacesChange(std::vector &ifaces) = 0; + + /** + * Notify the background policy change + * + * @param isBackgroundPolicyAllow The background is allow or not + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t NetBackgroundPolicyChange(bool isBackgroundPolicyAllow) = 0; + + /** + * @deprecated + */ + virtual int32_t NetStrategySwitch(const std::string &simId, bool enable) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_POLICY_CALLBACK_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_service.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_service.h new file mode 100644 index 00000000..54a7c0f4 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/i_net_policy_service.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_POLICY_SERVICE_H +#define I_NET_POLICY_SERVICE_H + +#include "iremote_broker.h" + +#include "i_net_policy_callback.h" +#include "net_policy_constants.h" +#include "net_quota_policy.h" +#include "policy_ipc_interface_code.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetPolicyService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetPolicyService"); + +public: + /** + * Set the network policy for the specified UID. + * + * @param uid The specified UID of app. + * @param policy The network policy for application. + * For details, see {@link NetUidPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetPolicyByUid(uint32_t uid, uint32_t policy) = 0; + + /** + * Get the network policy of the specified UID. + * + * @param uid The specified UID of app. + * @param policy Return this uid's policy. + * For details, see {@link NetUidPolicy}. + * int32_t Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetPolicyByUid(uint32_t uid, uint32_t &policy) = 0; + + /** + * Get the application UIDs of the specified policy. + * + * @param policy the network policy of the current UID of application. + * For details, see {@link NetUidPolicy}. + * @param uids The list of UIDs + * @return int32_t Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetUidsByPolicy(uint32_t policy, std::vector &uids) = 0; + + /** + * Get the status whether the specified uid app can access the metered network or non-metered network. + * + * @param uid The specified UID of application. + * @param metered Indicates metered network or non-metered network. + * @param isAllowed True means it's allowed to access the network. + * False means it's not allowed to access the network. + * @return Returns it's allowed or not to access the network. + */ + virtual int32_t IsUidNetAllowed(uint32_t uid, bool metered, bool &isAllowed) = 0; + + /** + * Get the status whether the specified uid app can access the specified iface network. + * + * @param uid The specified UID of application. + * @param ifaceName Iface name. + * @param isAllowed True means it's allowed to access the network. + * False means it's not allowed to access the network. + * @return int32_t Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t IsUidNetAllowed(uint32_t uid, const std::string &ifaceName, bool &isAllowed) = 0; + + /** + * Register network policy change callback. + * + * @param callback The callback of INetPolicyCallback interface. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t RegisterNetPolicyCallback(const sptr &callback) = 0; + + /** + * Unregister network policy change callback. + * + * @param callback The callback of INetPolicyCallback interface. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t UnregisterNetPolicyCallback(const sptr &callback) = 0; + + /** + * Set network policies. + * + * @param quotaPolicies The list of network quota policy, {@link NetQuotaPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetNetQuotaPolicies(const std::vector "aPolicies) = 0; + + /** + * Get network policies. + * + * @param quotaPolicies The list of network quota policy, {@link NetQuotaPolicy}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetNetQuotaPolicies(std::vector "aPolicies) = 0; + + /** + * Update the limit or warning remind time of quota policy. + * + * @param netType {@link NetBearType}. + * @param simId Specify the matched simId of quota policy when netType is cellular. + * @param remindType {@link RemindType}. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t UpdateRemindPolicy(int32_t netType, const std::string &simId, uint32_t remindType) = 0; + + /** + * Set the UID into device idle allow list. + * + * @param uid The specified UID of application. + * @param isAllowed The UID is into allow list or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetDeviceIdleTrustlist(const std::vector &uids, bool isAllowed) = 0; + + /** + * Get the allow list of UID in device idle mode. + * + * @param uids The list of UIDs + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetDeviceIdleTrustlist(std::vector &uids) = 0; + + /** + * Process network policy in device idle mode. + * + * @param enable Device idle mode is open or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetDeviceIdlePolicy(bool enable) = 0; + + /** + * Reset network policies\rules\quota policies\firewall rules. + * + * @param simId Specify the matched simId of quota policy. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t ResetPolicies(const std::string &simId) = 0; + + /** + * Control if apps can use data on background. + * + * @param isAllowed Allow apps to use data on background. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetBackgroundPolicy(bool isAllowed) = 0; + + /** + * Get the status if apps can use data on background. + * + * @param backgroundPolicy True is allowed to use data on background. + * False is not allowed to use data on background. + * @return int32_t Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetBackgroundPolicy(bool &backgroundPolicy) = 0; + + /** + * Get the background network restriction policy for the specified uid. + * + * @param uid The specified UID of application. + * @param backgroundPolicyOfUid The specified UID of backgroundPolicy. + * For details, see {@link NetBackgroundPolicy}. + * @return uint32_t Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetBackgroundPolicyByUid(uint32_t uid, uint32_t &backgroundPolicyOfUid) = 0; + + /** + * Get the Power Save Allowed List object + * + * @param uids The list of UIDs + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t GetPowerSaveTrustlist(std::vector &uids) = 0; + + /** + * Set the Power Save Allowed List object + * + * @param uid The specified UID of application. + * @param isAllowed The UID is into allow list or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetPowerSaveTrustlist(const std::vector &uids, bool isAllowed) = 0; + + /** + * Set the Power Save Policy object + * + * @param enable Power save mode is open or not. + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t SetPowerSavePolicy(bool enable) = 0; + + /** + * Check if you have permission + * + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + */ + virtual int32_t CheckPermission() = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_POLICY_SERVICE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_callback_stub.h new file mode 100644 index 00000000..8fd85723 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_callback_stub.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_POLICY_CALLBACK_STUB_H +#define NET_POLICY_CALLBACK_STUB_H + +#include + +#include "iremote_stub.h" + +#include "i_net_policy_callback.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetPolicyCallbackStub : public IRemoteStub { +public: + NetPolicyCallbackStub(); + virtual ~NetPolicyCallbackStub(); + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +public: + int32_t NetUidPolicyChange(uint32_t uid, uint32_t policy) override; + int32_t NetUidRuleChange(uint32_t uid, uint32_t rule) override; + int32_t NetQuotaPolicyChange(const std::vector "aPolicies) override; + int32_t NetStrategySwitch(const std::string &simId, bool enable) override; + int32_t NetMeteredIfacesChange(std::vector &ifaces) override; + int32_t NetBackgroundPolicyChange(bool isBackgroundPolicyAllow) override; + +private: + using NetPolicyCallbackFunc = int32_t (NetPolicyCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t OnNetUidPolicyChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetUidRuleChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetQuotaPolicyChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetStrategySwitch(MessageParcel &data, MessageParcel &reply); + int32_t OnNetMeteredIfacesChange(MessageParcel &data, MessageParcel &reply); + int32_t OnNetBackgroundPolicyChange(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_POLICY_CALLBACK_STUB_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_service_proxy.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_service_proxy.h new file mode 100644 index 00000000..32491975 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/net_policy_service_proxy.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_POLICY_SERVICE_PROXY_H +#define NET_POLICY_SERVICE_PROXY_H + +#include "iremote_proxy.h" + +#include "i_net_policy_service.h" +#include "net_policy_constants.h" +#include "net_quota_policy.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetPolicyServiceProxy : public IRemoteProxy { +public: + explicit NetPolicyServiceProxy(const sptr &impl); + virtual ~NetPolicyServiceProxy(); + int32_t SetPolicyByUid(uint32_t uid, uint32_t policy) override; + int32_t GetPolicyByUid(uint32_t uid, uint32_t &policy) override; + int32_t GetUidsByPolicy(uint32_t policy, std::vector &uids) override; + int32_t IsUidNetAllowed(uint32_t uid, bool metered, bool &isAllowed) override; + int32_t IsUidNetAllowed(uint32_t uid, const std::string &ifaceName, bool &isAllowed) override; + int32_t RegisterNetPolicyCallback(const sptr &callback) override; + int32_t UnregisterNetPolicyCallback(const sptr &callback) override; + int32_t SetNetQuotaPolicies(const std::vector "aPolicies) override; + int32_t GetNetQuotaPolicies(std::vector "aPolicies) override; + int32_t ResetPolicies(const std::string &simId) override; + int32_t SetBackgroundPolicy(bool allowBackground) override; + int32_t GetBackgroundPolicy(bool &backgroundPolicy) override; + int32_t GetBackgroundPolicyByUid(uint32_t uid, uint32_t &backgroundPolicyOfUid) override; + int32_t UpdateRemindPolicy(int32_t netType, const std::string &simId, uint32_t remindType) override; + int32_t SetDeviceIdleTrustlist(const std::vector &uids, bool isAllowed) override; + int32_t GetDeviceIdleTrustlist(std::vector &uids) override; + int32_t SetDeviceIdlePolicy(bool enable) override; + int32_t GetPowerSaveTrustlist(std::vector &uids) override; + int32_t SetPowerSaveTrustlist(const std::vector &uids, bool isAllowed) override; + int32_t SetPowerSavePolicy(bool enable) override; + int32_t CheckPermission() override; + +private: + bool WriteInterfaceToken(MessageParcel &data); + int32_t SendRequest(sptr &remote, uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_POLICY_SERVICE_PROXY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/policy_ipc_interface_code.h b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/policy_ipc_interface_code.h new file mode 100644 index 00000000..47faebbc --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/include/proxy/policy_ipc_interface_code.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef POLICY_IPC_INTERFACE_CODE_H +#define POLICY_IPC_INTERFACE_CODE_H + +/* SAID: 1152 */ +namespace OHOS { +namespace NetManagerStandard { +enum class PolicyInterfaceCode { + CMD_NPS_START = 0, + CMD_NPS_SET_POLICY_BY_UID, + CMD_NPS_GET_POLICY_BY_UID, + CMD_NPS_GET_UIDS_BY_POLICY, + CMD_NPS_IS_NET_ALLOWED_BY_METERED, + CMD_NPS_IS_NET_ALLOWED_BY_IFACE, + CMD_NPS_REGISTER_NET_POLICY_CALLBACK, + CMD_NPS_UNREGISTER_NET_POLICY_CALLBACK, + CMD_NPS_SET_NET_QUOTA_POLICIES, + CMD_NPS_GET_NET_QUOTA_POLICIES, + CMD_NPS_UPDATE_REMIND_POLICY, + CMD_NPS_SET_IDLE_TRUSTLIST, + CMD_NPS_GET_IDLE_TRUSTLIST, + CMD_NPS_SET_DEVICE_IDLE_POLICY, + CMD_NPS_RESET_POLICIES, + CMD_NPS_SET_BACKGROUND_POLICY, + CMD_NPS_GET_BACKGROUND_POLICY, + CMD_NPS_GET_BACKGROUND_POLICY_BY_UID, + CMD_NPS_SET_POWER_SAVE_TRUSTLIST, + CMD_NPS_GET_POWER_SAVE_TRUSTLIST, + CMD_NPS_SET_POWER_SAVE_POLICY, + CMD_NPS_CHECK_PERMISSION, + CMD_NPS_END = 100, +}; +enum class PolicyCallbackInterfaceCode { + NOTIFY_NET_UID_POLICY_CHANGE = 1, + NOTIFY_NET_UID_RULE_CHANGE = 2, + NOTIFY_NET_QUOTA_POLICY_CHANGE = 3, + NET_POLICY_STRATEGYSWITCH_CHANGE = 4, + NOTIFY_NET_METERED_IFACES_CHANGE = 5, + NOTIFY_BACKGROUND_POLICY_CHANGE = 6, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // POLICY_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netpolicyclient/libnetpolicy_kits.map b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/libnetpolicy_kits.map new file mode 100644 index 00000000..35ae36e6 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netpolicyclient/libnetpolicy_kits.map @@ -0,0 +1,73 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{ + global: + extern "C++" { + VTT?for?OHOS::NetManagerStandard::NetQuotaPolicy; + vtable?for?OHOS::NetManagerStandard::NetQuotaPolicy; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::~NetPolicyCallbackStub()"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetStrategySwitch(std::__h::basic_string, std::__h::allocator> const&, bool)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetStrategySwitch(std::__h::basic_string, std::__h::allocator> const&, bool)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::~NetPolicyCallbackStub()"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetUidPolicyChange(unsigned int, unsigned int)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetUidRuleChange(unsigned int, unsigned int)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetQuotaPolicyChange(std::__h::vector> const&)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetMeteredIfacesChange(std::__h::vector, std::__h::allocator>, std::__h::allocator, std::__h::allocator>>>&)"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetBackgroundPolicyChange(bool)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::~NetPolicyCallbackStub()"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetUidPolicyChange(unsigned int, unsigned int)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetUidRuleChange(unsigned int, unsigned int)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetQuotaPolicyChange(std::__h::vector> const&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetMeteredIfacesChange(std::__h::vector, std::__h::allocator>, std::__h::allocator, std::__h::allocator>>>&)"; + "non-virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::NetBackgroundPolicyChange(bool)"; + "virtual thunk to OHOS::NetManagerStandard::NetPolicyCallbackStub::~NetPolicyCallbackStub()"; + "OHOS::NetManagerStandard::NetPolicyClient::SetPolicyByUid(unsigned int, unsigned int)"; + "OHOS::NetManagerStandard::NetPolicyClient::NetPolicyClient()"; + "OHOS::NetManagerStandard::NetPolicyClient::GetPolicyByUid(unsigned int, unsigned int&)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetUidsByPolicy(unsigned int, std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetBackgroundPolicy(bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetBackgroundPolicy(bool&)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetNetQuotaPolicies(std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetNetQuotaPolicies(std::__h::vector> const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::ResetPolicies(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::IsUidNetAllowed(unsigned int, bool, bool&)"; + "OHOS::NetManagerStandard::NetPolicyClient::IsUidNetAllowed(unsigned int, std::__h::basic_string, std::__h::allocator> const&, bool&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetDeviceIdleTrustlist(unsigned int, bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetDeviceIdleTrustlist(std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetBackgroundPolicyByUid(unsigned int, unsigned int&)"; + "OHOS::NetManagerStandard::NetPolicyClient::UpdateRemindPolicy(int, std::__h::basic_string, std::__h::allocator> const&, unsigned int)"; + "OHOS::NetManagerStandard::NetPolrooticyClient::~NetPolicyClient()"; + "OHOS::NetManagerStandard::NetPolicyCallbackStub::NetPolicyCallbackStub()"; + "OHOS::NetManagerStandard::NetPolicyClient::RegisterNetPolicyCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::UnregisterNetPolicyCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::~NetPolicyClient()"; + "OHOS::NetManagerStandard::NetPolicyClient::SetPowerSaveTrustlist(unsigned int, bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetPowerSaveTrustlist(std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetDeviceIdlePolicy(bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::IsUidNetAccess(unsigned int, bool, bool&)"; + "OHOS::NetManagerStandard::NetPolicyClient::IsUidNetAccess(unsigned int, std::__h::basic_string, std::__h::allocator> const&, bool&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetFactoryPolicy(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetSnoozePolicy(signed char, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetIdleTrustlist(unsigned int, bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::GetIdleTrustlist(std::__h::vector>&)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetDeviceIdleTrustlist(std::__h::vector> const&, bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetPowerSaveTrustlist(std::__h::vector> const&, bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::SetPowerSavePolicy(bool)"; + "OHOS::NetManagerStandard::NetPolicyClient::CheckPermission()"; + "OHOS::NetManagerStandard::NetPolicyClient::OnRemoteDied(OHOS::wptr const&)"; + }; + local: + *; +}; \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/BUILD.gn b/mock/innerkits/netmanager_base/innerkits/netstatsclient/BUILD.gn new file mode 100644 index 00000000..25abb930 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/BUILD.gn @@ -0,0 +1,104 @@ +# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/netmanager_base/netmanager_base_config.gni") + +config("net_stats_manager_if_config") { + # header file path + include_dirs = [ + "$INNERKITS_ROOT/include", + "$INNERKITS_ROOT/netstatsclient/include/proxy", + "$INNERKITS_ROOT/netstatsclient/include", + "$INNERKITS_ROOT/netmanagernative/include", + "$NETSYSNATIVE_SOURCE_DIR/include/netsys", + ] + + cflags = [] + if (is_double_framework) { + cflags += [ "-DCONFIG_DUAL_FRAMEWORK" ] + } + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + if (is_standard_system) { + cflags += [ "-DCONFIG_STANDARD_SYSTEM" ] + } + if (defined(build_public_version) && build_public_version) { + cflags += [ "-DBUILD_PUBLIC_VERSION" ] + } +} + +ohos_source_set("net_stats_parcel") { + sources = [ "$NETSTATSMANAGER_INNERKITS_SOURCE_DIR/src/net_stats_info.cpp" ] + + include_dirs = [ "$INNERKITS_ROOT/netstatsclient/include" ] + + deps = [ "$NETMANAGER_BASE_ROOT/utils:net_manager_common" ] + external_deps = [ "c_utils:utils" ] + external_deps += [ "hilog:libhilog" ] + + part_name = "netmanager_base" + subsystem_name = "communication" +} + +ohos_shared_library("net_stats_manager_if") { + sanitize = { + cfi = true + cfi_cross_dso = true + integer_overflow = true + boundary_sanitize = true + all_ubsan = true + } + + sources = [ + "$NETSTATSMANAGER_INNERKITS_SOURCE_DIR/src/data_flow_statistics.cpp", + "$NETSTATSMANAGER_INNERKITS_SOURCE_DIR/src/net_stats_client.cpp", + "$NETSTATSMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_stats_callback_stub.cpp", + "$NETSTATSMANAGER_INNERKITS_SOURCE_DIR/src/proxy/net_stats_service_proxy.cpp", + ] + + include_dirs = [ + "$NETMANAGER_BASE_ROOT/utils/log/include", + "$NETSYSCONTROLLER_ROOT_DIR/include/", + ] + + version_script = "libnetstats_kits.map" + + public_configs = [ ":net_stats_manager_if_config" ] + + deps = [ + ":net_stats_parcel", + "$NETSYSCONTROLLER_ROOT_DIR:netsys_controller", + ] + + external_deps = [ + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + defines = [ + "NETMGR_LOG_TAG = \"NetStatsClient\"", + "LOG_DOMAIN = 0xD0015B0", + ] + + if (enable_netmgr_debug) { + defines += [ "NETMGR_DEBUG" ] + } + + external_deps += [ "hilog:libhilog" ] + + innerapi_tags = [ "platformsdk" ] + part_name = "netmanager_base" + subsystem_name = "communication" +} diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/data_flow_statistics.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/data_flow_statistics.h new file mode 100644 index 00000000..1aa5261f --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/data_flow_statistics.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_FLOW_STATISTICS_H +#define DATA_FLOW_STATISTICS_H + +#include + +namespace OHOS { +namespace NetManagerStandard { +class DataFlowStatistics { +public: + DataFlowStatistics() = default; + ~DataFlowStatistics() = default; + + /** + * Obtains the bytes received over the cellular network. + * + * @return The number of received bytes. + */ + int64_t GetCellularRxBytes(); + + /** + * Obtains the bytes sent over the cellular network. + * + * @return The number of sent bytes. + */ + int64_t GetCellularTxBytes(); + + /** + * Obtains the bytes received through all NICs. + * + * @return The number of received bytes. + */ + int64_t GetAllRxBytes(); + + /** + * Obtains the bytes sent through all NICs. + * + * @return The number of sent bytes. + */ + int64_t GetAllTxBytes(); + + /** + * Obtains the bytes received through a specified UID. + * + * @param uid + * @return The number of received bytes. + */ + int64_t GetUidRxBytes(uint32_t uid); + + /** + * Obtains the bytes sent through a specified UID. + * + * @param uid + * @return The number of sent bytes. + */ + int64_t GetUidTxBytes(uint32_t uid); + + /** + * Obtains the bytes received through a specified NIC. + * + * @param iface The name of the interface. + * @return The number of received bytes. + */ + int64_t GetIfaceRxBytes(const std::string &interfaceName); + + /** + * Obtains the bytes sent through a specified NIC. + * + * @param iface The name of the interface. + * @return The number of sent bytes. + */ + int64_t GetIfaceTxBytes(const std::string &interfaceName); + + /** + * Obtains the packets received through a specified NIC. + * + * @param iface The name of the interface. + * @return The number of received packets. + */ + int64_t GetIfaceRxPackets(const std::string &interfaceName); + + /** + * Obtains the packets sent through a specified NIC. + * + * @param iface The name of the interface. + * @return The number of sent packets. + */ + int64_t GetIfaceTxPackets(const std::string &interfaceName); +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // DATA_FLOW_STATISTICS_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_client.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_client.h new file mode 100644 index 00000000..ab4fc318 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_client.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_STATS_CLIENT_H +#define NET_STATS_CLIENT_H + +#include + +#include "parcel.h" +#include "singleton.h" + +#include "i_net_stats_service.h" +#include "net_stats_constants.h" +#include "net_stats_info.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetStatsClient : public Singleton { +public: + NetStatsClient(); + ~NetStatsClient(); + + /** + * Register network card traffic monitoring + * + * @param callback callback function + * @return Returns 0 success. Otherwise fail, {@link NetPolicyResultCode}. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t RegisterNetStatsCallback(const sptr &callback); + + /** + * Unregister network card traffic monitoring + * + * @param callback callback function + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UnregisterNetStatsCallback(const sptr &callback); + + /** + * Get the received traffic of the network card + * + * @param stats Traffic (bytes) + * @param interfaceName network card name + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetIfaceRxBytes(uint64_t &stats, const std::string &interfaceName); + + /** + * Get the send traffic of the network card + * + * @param stats Traffic (bytes) + * @param interfaceName network card name + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetIfaceTxBytes(uint64_t &stats, const std::string &interfaceName); + + /** + * Get received traffic from the cell + * + * @param stats Traffic (bytes) + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetCellularRxBytes(uint64_t &stats); + + /** + * Get send traffic from the cell + * + * @param stats Traffic (bytes) + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetCellularTxBytes(uint64_t &stats); + + /** + * Get all received traffic + * + * @param stats Traffic (bytes) + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAllRxBytes(uint64_t &stats); + + /** + * Get all send traffic + * + * @param stats Traffic (bytes) + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAllTxBytes(uint64_t &stats); + + /** + * Get the received traffic for the specified UID of application + * + * @param stats Traffic (bytes) + * @param uid The specified UID of application. + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetUidRxBytes(uint64_t &stats, uint32_t uid); + + /** + * Get the send traffic for the specified UID of application + * + * @param stats Traffic (bytes) + * @param uid The specified UID of application. + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetUidTxBytes(uint64_t &stats, uint32_t uid); + + /** + * Get traffic details for all network cards + * + * @param infos all network cards informations + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetAllStatsInfo(std::vector &infos); + + /** + * Get the historical traffic details of the specified network card + * + * @param iface network cards name + * @param start start time + * @param end end time + * @param statsInfo traffic information + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetIfaceStatsDetail(const std::string &iface, uint64_t start, uint64_t end, NetStatsInfo &statsInfo); + + /** + * Get the historical traffic details from UID of application. + * + * @param iface network cards name + * @param uid The specified UID of application. + * @param start start time + * @param end end time + * @param statsInfo traffic information + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t GetUidStatsDetail(const std::string &iface, uint32_t uid, uint64_t start, uint64_t end, + NetStatsInfo &statsInfo); + + /** + * Update the traffic of the specified network card + * + * @param iface network cards name + * @param start start time + * @param end end time + * @param stats Traffic (bytes) + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UpdateIfacesStats(const std::string &iface, uint64_t start, uint64_t end, const NetStatsInfo &stats); + + /** + * Update network card traffic data + * + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t UpdateStatsData(); + + /** + * Clear network card traffic + * + * @return Returns 0 success. Otherwise fail. + * @permission ohos.permission.CONNECTIVITY_INTERNAL + * @systemapi Hide this for inner system use. + */ + int32_t ResetFactory(); + +private: + class NetStatsDeathRecipient : public IRemoteObject::DeathRecipient { + public: + explicit NetStatsDeathRecipient(NetStatsClient &client) : client_(client) {} + ~NetStatsDeathRecipient() override = default; + void OnRemoteDied(const wptr &remote) override + { + client_.OnRemoteDied(remote); + } + + private: + NetStatsClient &client_; + }; + +private: + sptr GetProxy(); + void OnRemoteDied(const wptr &remote); + +private: + std::mutex mutex_; + sptr netStatsService_; + sptr deathRecipient_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_STATS_CLIENT_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_constants.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_constants.h new file mode 100644 index 00000000..3776ff7d --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_constants.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_STATS_CONSTANTS_H +#define NET_STATS_CONSTANTS_H + +#include "net_manager_constants.h" + +namespace OHOS { +namespace NetManagerStandard { +constexpr int16_t LIMIT_STATS_CALLBACK_NUM = 200; +enum NetStatsResultCode { + STATS_DUMP_MESSAGE_FAIL = 2103002, + STATS_REMOVE_FILE_FAIL, + STATS_ERR_INVALID_TIME_PERIOD, + STATS_ERR_READ_BPF_FAIL, + STATS_ERR_INVALID_KEY, + STATS_ERR_INVALID_IFACE_STATS_MAP, + STATS_ERR_INVALID_STATS_VALUE, + STATS_ERR_INVALID_STATS_TYPE, + STATS_ERR_INVALID_UID_STATS_MAP, + STATS_ERR_INVALID_IFACE_NAME_MAP, + STATS_ERR_GET_IFACE_NAME_FAILED, + STATS_ERR_CLEAR_STATS_DATA_FAIL, + STATS_ERR_CREATE_TABLE_FAIL, + STATS_ERR_DATABASE_RECV_NO_DATA, + STATS_ERR_WRITE_DATA_FAIL, + STATS_ERR_READ_DATA_FAIL, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_STATS_CONSTANTS_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_info.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_info.h new file mode 100644 index 00000000..bfc11f62 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/net_stats_info.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_STATS_INFO_H +#define NET_STATS_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace NetManagerStandard { +struct NetStatsInfo final : public Parcelable { + uint32_t uid_ = 0; + std::string iface_; + uint64_t date_ = 0; + uint64_t rxBytes_ = 0; + uint64_t txBytes_ = 0; + uint64_t rxPackets_ = 0; + uint64_t txPackets_ = 0; + + inline const std::string UidData() const + { + return std::to_string(uid_) + ",'" + iface_ + "'," + std::to_string(date_) + "," + std::to_string(rxBytes_) + + "," + std::to_string(rxPackets_) + "," + std::to_string(txBytes_) + "," + std::to_string(txPackets_); + } + + inline const std::string IfaceData() const + { + return "'" + iface_ + "'," + std::to_string(date_) + "," + std::to_string(rxBytes_) + "," + + std::to_string(rxPackets_) + "," + std::to_string(txBytes_) + "," + std::to_string(txPackets_); + } + + inline uint64_t GetStats() const + { + return rxBytes_ + txBytes_; + } + + inline bool Equals(const NetStatsInfo &info) const + { + return info.uid_ == uid_ && info.iface_ == iface_; + } + + inline bool HasNoData() const + { + return rxBytes_ == 0 && rxPackets_ == 0 && txBytes_ == 0 && txPackets_ == 0; + } + + const NetStatsInfo operator-(const NetStatsInfo &other) const + { + NetStatsInfo info; + info.uid_ = other.uid_; + info.iface_ = other.iface_; + info.rxPackets_ = (rxPackets_ > other.rxPackets_) ? rxPackets_ - other.rxPackets_ : 0; + info.rxBytes_ = (rxBytes_ > other.rxBytes_) ? rxBytes_ - other.rxBytes_ : 0; + info.txPackets_ = (txPackets_ > other.txPackets_) ? txPackets_ - other.txPackets_ : 0; + info.txBytes_ = (txBytes_ > other.txBytes_) ? txBytes_ - other.txBytes_ : 0; + return info; + } + + NetStatsInfo &operator+=(const NetStatsInfo &other) + { + rxPackets_ += other.rxPackets_; + rxBytes_ += other.rxBytes_; + txPackets_ += other.txPackets_; + txBytes_ += other.txBytes_; + return *this; + } + + bool Marshalling(Parcel &parcel) const override; + static bool Marshalling(Parcel &parcel, const NetStatsInfo &stats); + static bool Marshalling(Parcel &parcel, const std::vector &statsInfos); + static bool Unmarshalling(Parcel &parcel, NetStatsInfo &stats); + static bool Unmarshalling(Parcel &parcel, std::vector &statsInfos); +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_STATS_INFO_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_callback.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_callback.h new file mode 100644 index 00000000..1b05e936 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_callback.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_NET_STATS_CALLBACK_H +#define I_NET_STATS_CALLBACK_H + +#include + +#include "iremote_broker.h" +#include "stats_ipc_interface_code.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetStatsCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetStatsCallback"); + virtual ~INetStatsCallback() = default; + virtual int32_t NetIfaceStatsChanged(const std::string &iface) = 0; + virtual int32_t NetUidStatsChanged(const std::string &iface, uint32_t uid) = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_STATS_CALLBACK_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_service.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_service.h new file mode 100644 index 00000000..7d5441b8 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/i_net_stats_service.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021-20223 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 I_NET_STATS_SERVICE_H +#define I_NET_STATS_SERVICE_H + +#include + +#include "i_net_stats_callback.h" +#include "iremote_broker.h" +#include "net_stats_constants.h" +#include "net_stats_info.h" +#include "stats_ipc_interface_code.h" + +namespace OHOS { +namespace NetManagerStandard { +class INetStatsService : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.NetManagerStandard.INetStatsService"); + +public: + virtual int32_t GetIfaceRxBytes(uint64_t &stats, const std::string &interfaceName) = 0; + virtual int32_t GetIfaceTxBytes(uint64_t &stats, const std::string &interfaceName) = 0; + virtual int32_t GetCellularRxBytes(uint64_t &stats) = 0; + virtual int32_t GetCellularTxBytes(uint64_t &stats) = 0; + virtual int32_t GetAllRxBytes(uint64_t &stats) = 0; + virtual int32_t GetAllTxBytes(uint64_t &stats) = 0; + virtual int32_t GetUidRxBytes(uint64_t &stats, uint32_t uid) = 0; + virtual int32_t GetUidTxBytes(uint64_t &stats, uint32_t uid) = 0; + virtual int32_t GetAllStatsInfo(std::vector &info) = 0; + virtual int32_t RegisterNetStatsCallback(const sptr &callback) = 0; + virtual int32_t UnregisterNetStatsCallback(const sptr &callback) = 0; + virtual int32_t GetIfaceStatsDetail(const std::string &iface, uint64_t start, uint64_t end, + NetStatsInfo &statsInfo) = 0; + virtual int32_t GetUidStatsDetail(const std::string &iface, uint32_t uid, uint64_t start, uint64_t end, + NetStatsInfo &statsInfo) = 0; + virtual int32_t UpdateIfacesStats(const std::string &iface, uint64_t start, uint64_t end, + const NetStatsInfo &stats) = 0; + virtual int32_t UpdateStatsData() = 0; + virtual int32_t ResetFactory() = 0; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // I_NET_STATS_SERVICE_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_callback_stub.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_callback_stub.h new file mode 100644 index 00000000..9d7e98e7 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_callback_stub.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_STATS_CALLBACK_STUB_H +#define NET_STATS_CALLBACK_STUB_H + +#include + +#include "iremote_stub.h" + +#include "i_net_stats_callback.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetStatsCallbackStub : public IRemoteStub { +public: + NetStatsCallbackStub(); + virtual ~NetStatsCallbackStub(); + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using NetStatsCallbackFunc = int32_t (NetStatsCallbackStub::*)(MessageParcel &, MessageParcel &); + +private: + int32_t OnNetIfaceStatsChanged(MessageParcel &data, MessageParcel &reply); + int32_t OnNetUidStatsChanged(MessageParcel &data, MessageParcel &reply); + +private: + std::map memberFuncMap_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_STATS_CALLBACK_STUB_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_service_proxy.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_service_proxy.h new file mode 100644 index 00000000..437268f3 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/net_stats_service_proxy.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NET_STATS_SERVICE_PROXY_H +#define NET_STATS_SERVICE_PROXY_H + +#include "i_net_stats_service.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace NetManagerStandard { +class NetStatsServiceProxy : public IRemoteProxy { +public: + explicit NetStatsServiceProxy(const sptr &impl); + virtual ~NetStatsServiceProxy(); + int32_t RegisterNetStatsCallback(const sptr &callback) override; + int32_t UnregisterNetStatsCallback(const sptr &callback) override; + int32_t GetIfaceRxBytes(uint64_t &stats, const std::string &interfaceName) override; + int32_t GetIfaceTxBytes(uint64_t &stats, const std::string &interfaceName) override; + int32_t GetCellularRxBytes(uint64_t &stats) override; + int32_t GetCellularTxBytes(uint64_t &stats) override; + int32_t GetAllRxBytes(uint64_t &stats) override; + int32_t GetAllTxBytes(uint64_t &stats) override; + int32_t GetUidRxBytes(uint64_t &stats, uint32_t uid) override; + int32_t GetUidTxBytes(uint64_t &stats, uint32_t uid) override; + int32_t GetAllStatsInfo(std::vector &infos) override; + int32_t GetIfaceStatsDetail(const std::string &iface, uint64_t start, uint64_t end, + NetStatsInfo &statsInfo) override; + int32_t GetUidStatsDetail(const std::string &iface, uint32_t uid, uint64_t start, uint64_t end, + NetStatsInfo &statsInfo) override; + int32_t UpdateIfacesStats(const std::string &iface, uint64_t start, uint64_t end, + const NetStatsInfo &stats) override; + int32_t UpdateStatsData() override; + int32_t ResetFactory() override; + +private: + bool WriteInterfaceToken(MessageParcel &data); + int32_t SendRequest(sptr &remote, uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // NET_STATS_SERVICE_PROXY_H diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/stats_ipc_interface_code.h b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/stats_ipc_interface_code.h new file mode 100644 index 00000000..be78e58b --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/include/proxy/stats_ipc_interface_code.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef STATS_IPC_INTERFACE_CODE_H +#define STATS_IPC_INTERFACE_CODE_H + +/* SAID: 1153 */ +namespace OHOS { +namespace NetManagerStandard { +enum class StatsCallBackInterfaceCode { + NET_STATS_IFACE_CHANGED = 0, + NET_STATS_UID_CHANGED = 1, +}; + +enum class StatsInterfaceCode { + CMD_START = 0, + CMD_SYSTEM_READY, + CMD_GET_IFACE_STATS_DETAIL, + CMD_GET_UID_STATS_DETAIL, + CMD_UPDATE_IFACES_STATS, + CMD_UPDATE_STATS_DATA, + CMD_NSM_REGISTER_NET_STATS_CALLBACK, + CMD_NSM_UNREGISTER_NET_STATS_CALLBACK, + CMD_NSM_RESET_FACTORY, + CMD_GET_IFACE_RXBYTES, + CMD_GET_IFACE_TXBYTES, + CMD_GET_CELLULAR_RXBYTES, + CMD_GET_CELLULAR_TXBYTES, + CMD_GET_ALL_RXBYTES, + CMD_GET_ALL_TXBYTES, + CMD_GET_UID_RXBYTES, + CMD_GET_UID_TXBYTES, + CMD_GET_ALL_STATS_INFO, + CMD_END = 100, +}; +} // namespace NetManagerStandard +} // namespace OHOS +#endif // STATS_IPC_INTERFACE_CODE_H \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/innerkits/netstatsclient/libnetstats_kits.map b/mock/innerkits/netmanager_base/innerkits/netstatsclient/libnetstats_kits.map new file mode 100644 index 00000000..9d191aa5 --- /dev/null +++ b/mock/innerkits/netmanager_base/innerkits/netstatsclient/libnetstats_kits.map @@ -0,0 +1,97 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{ + global: + extern "C++" { + VTT?for?OHOS::NetManagerStandard::NetStatsInfo; + vtable?for?OHOS::NetManagerStandard::NetStatsInfo; + "non-virtual thunk to OHOS::NetManagerStandard::NetStatsCallbackStub::~NetStatsCallbackStub()"; + "virtual thunk to OHOS::NetManagerStandard::NetStatsCallbackStub::~NetStatsCallbackStub()"; + "OHOS::NetManagerStandard::NetStatsClient::GetCellularRxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsClient::NetStatsClient()"; + "OHOS::NetManagerStandard::NetStatsClient::GetCellularTxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetAllRxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetAllTxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidRxBytes(unsigned long long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidTxBytes(unsigned long long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceRxBytes(unsigned long long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceTxBytes(unsigned long long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned int, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsClient::UpdateIfacesStats(std::__h::basic_string, std::__h::allocator> const&, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo const&)"; + "OHOS::NetManagerStandard::NetStatsClient::UpdateStatsData()"; + "OHOS::NetManagerStandard::NetStatsClient::~NetStatsClient()"; + "OHOS::NetManagerStandard::NetStatsClient::ResetFactory()"; + "OHOS::NetManagerStandard::NetStatsClient::OnRemoteDied(OHOS::wptr const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetCellularRxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetCellularTxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetAllRxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetAllTxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidRxBytes(unsigned long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidTxBytes(unsigned long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceRxBytes(unsigned long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceTxBytes(unsigned long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetIfaceStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetUidStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned int, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsClient::UpdateIfacesStats(std::__h::basic_string, std::__h::allocator> const&, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo const&)"; + "OHOS::NetManagerStandard::NetStatsClient::RegisterNetStatsCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetStatsClient::UnregisterNetStatsCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetStatsClient::GetAllStatsInfo(std::__h::vector>&)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceTxPackets(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceRxPackets(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetCellularRxBytes()"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetCellularTxBytes()"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetAllRxBytes()"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetAllTxBytes()"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetUidTxBytes(unsigned int)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceRxBytes(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::DataFlowStatistics::GetIfaceTxBytes(std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsCallbackStub::~NetStatsCallbackStub()"; + "OHOS::NetManagerStandard::NetStatsCallbackStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)"; + "OHOS::NetManagerStandard::NetStatsCallbackStub::OnNetIfaceStatsChanged(OHOS::MessageParcel&, OHOS::MessageParcel&)"; + "OHOS::NetManagerStandard::NetStatsCallbackStub::OnNetUidStatsChanged(OHOS::MessageParcel&, OHOS::MessageParcel&)"; + "OHOS::NetManagerStandard::NetStatsCallbackStub::NetStatsCallbackStub()"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::NetStatsServiceProxy(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::RegisterNetStatsCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::~NetStatsServiceProxy()"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::UnregisterNetStatsCallback(OHOS::sptr const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceRxBytes(unsigned long long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceTxBytes(unsigned long long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetCellularRxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetCellularTxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetAllRxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetAllTxBytes(unsigned long long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidRxBytes(unsigned long long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidTxBytes(unsigned long long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned int, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::UpdateIfacesStats(std::__h::basic_string, std::__h::allocator> const&, unsigned long long, unsigned long long, OHOS::NetManagerStandard::NetStatsInfo const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::UpdateStatsData()"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::ResetFactory()"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceRxBytes(unsigned long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceTxBytes(unsigned long&, std::__h::basic_string, std::__h::allocator> const&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetCellularRxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetCellularTxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetAllRxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetAllTxBytes(unsigned long&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidRxBytes(unsigned long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidTxBytes(unsigned long&, unsigned int)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetIfaceStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::GetUidStatsDetail(std::__h::basic_string, std::__h::allocator> const&, unsigned int, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo&)"; + "OHOS::NetManagerStandard::NetStatsServiceProxy::UpdateIfacesStats(std::__h::basic_string, std::__h::allocator> const&, unsigned long, unsigned long, OHOS::NetManagerStandard::NetStatsInfo const&)"; + "OHOS::NetManagerStandard::NetStatsInfo::Unmarshalling(OHOS::Parcel&, std::__h::vector>&)"; + }; + local: + *; +}; \ No newline at end of file diff --git a/mock/innerkits/netmanager_base/net_policy_manager_if/include/net_policy_client.h b/mock/innerkits/netmanager_base/net_policy_manager_if/include/net_policy_client.h deleted file mode 100644 index 263364ba..00000000 --- a/mock/innerkits/netmanager_base/net_policy_manager_if/include/net_policy_client.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NET_POLICY_CLIENT_H -#define NET_POLICY_CLIENT_H - -#include "singleton.h" - -#include "i_net_policy_service.h" -#include "net_policy_cellular_policy.h" -#include "net_policy_constants.h" -#include "net_policy_quota_policy.h" - -namespace OHOS { -namespace NetManagerStandard { -class NetPolicyClient { - DECLARE_DELAYED_SINGLETON(NetPolicyClient) - -public: - /** - * @brief The interface is set uid policy - * - * @param uid uid - * @param policy policy - * - * @return Returns 0 success, otherwise fail - */ - NetPolicyResultCode SetPolicyByUid(uint32_t uid, NetUidPolicy policy); - /** - * @brief The interface is get uid policy - * - * @param uid uid - * @return Returns NetUidPolicy, otherwise fail - */ - NetUidPolicy GetPolicyByUid(uint32_t uid); - /** - * @brief The interface is get uids by policy - * - * @param policy policy - * @return uids - */ - std::vector GetUidsByPolicy(NetUidPolicy policy); - /** - * @brief The interface determine whether you have access to the network - * - * @param uid uid - * @param metered true/false - * @return bool - */ - bool IsUidNetAccess(uint32_t uid, bool metered); - /** - * @brief The interface determine whether you have access to the network - * - * @param uid uid - * @param ifaceName , you can get ifacename by GetIfaceNameByType - * @return bool - */ - bool IsUidNetAccess(uint32_t uid, const std::string &ifaceName); - /** - * @brief Register net policy callback - * - * @param callback The callback of INetPolicyCallback interface - * - * @return Returns 0, successfully register net policy callback, otherwise it will failed - */ - int32_t RegisterNetPolicyCallback(const sptr &callback); - /** - * @brief Unregister net policy callback - * - * @return Returns 0, successfully unregister net policy callback, otherwise it will fail - */ - int32_t UnregisterNetPolicyCallback(const sptr &callback); - /** - * @brief SetNetQuotaPolicies set policys by NetPolicyQuotaPolicy - * - * @return Returns 0, successfully - */ - NetPolicyResultCode SetNetQuotaPolicies(const std::vector "aPolicies); - /** - * @brief GetNetQuotaPolicies get policys for NetPolicyQuotaPolicy - * - * @return Returns 0, successfully - */ - NetPolicyResultCode GetNetQuotaPolicies(std::vector "aPolicies); - /** - * @brief SetCellularPolicies set policys by NetPolicyCellularPolicy - * - * @return Returns 0, successfully - */ - NetPolicyResultCode SetCellularPolicies(const std::vector &cellularPolicies); - /** - * @brief GetCellularPolicies get policys for NetPolicyCellularPolicy - * - * @return Returns 0, successfully - */ - NetPolicyResultCode GetCellularPolicies(std::vector &cellularPolicies); - /** - * @brief SetFactoryPolicy reset policys for simId - * - * @param simId ID, get from telephone module - * @return Returns 0, successfully - */ - NetPolicyResultCode SetFactoryPolicy(const std::string &simId); - /** - * @brief SetBackgroundPolicy reset backgroundpolicy for all app - * - * @param backgroundPolicy refuse app visit network - * @return Returns 0, successfully - */ - NetPolicyResultCode SetBackgroundPolicy(bool isBackgroundPolicyAllow); - /** - * @brief GetBackgroundPolicy get background policy - * - * @return bool - */ - bool GetBackgroundPolicy(); - /** - * @brief GetBackgroundPolicyByUid get background policy by uid - * - * @param uid uid - * @return bool - */ - bool GetBackgroundPolicyByUid(uint32_t uid); - /** - * @brief GetCurrentBackgroundPolicy get background policy by current - * - * @return Returns NetBackgroundPolicy - */ - NetBackgroundPolicy GetCurrentBackgroundPolicy(); - /** - * @brief SetSnoozePolicy for Hibernate current policy - * - * @return Returns 0, successfully - */ - NetPolicyResultCode SetSnoozePolicy(int8_t netType, const std::string &simId); - /** - * @brief SetIdleTrustlist for add trust list for Idle status - * - * @param uid uid - * @param isTrustlist true/false - * - * @return Returns 0, successfully - */ - NetPolicyResultCode SetIdleTrustlist(uint32_t uid, bool isTrustlist); - /** - * @brief GetIdleTrustlist for get trust list for Idle status - * - * @param uid uid - * @param uids - * - * @return Returns 0, successfully - */ - NetPolicyResultCode GetIdleTrustlist(std::vector &uids); - -private: - class NetPolicyDeathRecipient : public IRemoteObject::DeathRecipient { - public: - explicit NetPolicyDeathRecipient(NetPolicyClient &client) : client_(client) {} - ~NetPolicyDeathRecipient() override = default; - void OnRemoteDied(const wptr &remote) override - { - client_.OnRemoteDied(remote); - } - - private: - NetPolicyClient &client_; - }; - -private: - sptr GetProxy(); - void OnRemoteDied(const wptr &remote); - -private: - std::mutex mutex_; - sptr netPolicyService_; - sptr deathRecipient_; -}; -} // namespace NetManagerStandard -} // namespace OHOS -#endif // NET_POLICY_CLIENT_H diff --git a/mock/innerkits/netmanager_base/sdk_info.json b/mock/innerkits/netmanager_base/sdk_info.json deleted file mode 100644 index ee33e119..00000000 --- a/mock/innerkits/netmanager_base/sdk_info.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "net_conn_manager_if": { - "label": "//foundation/communication/netmanager_base/interfaces/innerkits/netconnclient:net_conn_manager_if(//build/toolchain/ohos:ohos_clang_arm64)", - "source": "net_conn_manager_if/libnet_conn_manager_if.z.so", - "type": "so" - }, - "net_policy_manager_if": { - "label": "//foundation/communication/netmanager_base/interfaces/innerkits/netpolicyclient:net_policy_manager_if(//build/toolchain/ohos:ohos_clang_arm64)", - "source": "net_policy_manager_if/libnet_policy_manager_if.z.so", - "type": "so" - }, - "net_stats_manager_if": { - "label": "//foundation/communication/netmanager_base/interfaces/innerkits/netstatsclient:net_stats_manager_if(//build/toolchain/ohos:ohos_clang_arm64)", - "source": "net_stats_manager_if/libnet_stats_manager_if.z.so", - "type": "so" - } -} \ No newline at end of file diff --git a/mock/kits/ability/appkit/ability_runtime/context/context.h b/mock/kits/ability/appkit/ability_runtime/context/context.h index f70b1c1f..9b5a6995 100644 --- a/mock/kits/ability/appkit/ability_runtime/context/context.h +++ b/mock/kits/ability/appkit/ability_runtime/context/context.h @@ -1,20 +1,20 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ABILITY_RUNTIME_CONTEXT_H -#define ABILITY_RUNTIME_CONTEXT_H +* Copyright (c) 2021-2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_ABILITY_RUNTIME_STAGE_CONTEXT_CONTEXT_H +#define OHOS_ABILITY_RUNTIME_STAGE_CONTEXT_CONTEXT_H #include #include @@ -38,197 +38,227 @@ public: ~Context() override = default; /** - * @brief Obtains the Context object of the application. - * - * @return Returns the Context object of the application. - */ + * @brief Obtains the Context object of the application. + * + * @return Returns the Context object of the application. + */ static std::shared_ptr GetApplicationContext(); /** - * @brief Obtains the bundle name of the current ability. - * - * @return Returns the bundle name of the current ability. - */ + * @brief Obtains the bundle name of the current ability. + * + * @return Returns the bundle name of the current ability. + */ virtual std::string GetBundleName() const = 0; /** - * @brief Creates a Context object for an application with the given bundle name. - * - * @param bundleName Indicates the bundle name of the application. - * - * @return Returns a Context object created for the specified application. - */ + * @brief Creates a Context object for an application with the given bundle name. + * + * @param bundleName Indicates the bundle name of the application. + * + * @return Returns a Context object created for the specified application. + */ virtual std::shared_ptr CreateBundleContext(const std::string &bundleName) = 0; /** - * @brief Obtains information about the current application. The returned application information includes basic - * information such as the application name and application permissions. - * - * @return Returns the ApplicationInfo for the current application. - */ + * @brief Obtains information about the current application. The returned application information includes basic + * information such as the application name and application permissions. + * + * @return Returns the ApplicationInfo for the current application. + */ virtual std::shared_ptr GetApplicationInfo() const = 0; /** - * @brief Obtains a resource manager. - * - * @return Returns a ResourceManager object. - */ + * @brief Obtains a resource manager. + * + * @return Returns a ResourceManager object. + */ virtual std::shared_ptr GetResourceManager() const = 0; /** - * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, - * source code, and configuration files of a module. - * - * @return Returns the path of the package file. - */ + * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, + * source code, and configuration files of a module. + * + * @return Returns the path of the package file. + */ virtual std::string GetBundleCodePath() const = 0; /** - * @brief Obtains the HapModuleInfo object of the application. - * - * @return Returns the HapModuleInfo object of the application. - */ + * @brief Obtains the HapModuleInfo object of the application. + * + * @return Returns the HapModuleInfo object of the application. + */ virtual std::shared_ptr GetHapModuleInfo() const = 0; /** - * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, - * source code, and configuration files of a module. - * - * @return Returns the path of the package file. - */ + * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, + * source code, and configuration files of a module. + * + * @return Returns the path of the package file. + */ virtual std::string GetBundleCodeDir() = 0; /** - * @brief Obtains the application-specific cache directory on the device's internal storage. The system - * automatically deletes files from the cache directory if disk space is required elsewhere on the device. - * Older files are always deleted first. - * - * @return Returns the application-specific cache directory. - */ + * @brief Obtains the application-specific cache directory on the device's internal storage. The system + * automatically deletes files from the cache directory if disk space is required elsewhere on the device. + * Older files are always deleted first. + * + * @return Returns the application-specific cache directory. + */ virtual std::string GetCacheDir() = 0; /** - * @brief Obtains the temporary directory. - * - * @return Returns the application temporary directory. - */ + * @brief Obtains the temporary directory. + * + * @return Returns the application temporary directory. + */ virtual std::string GetTempDir() = 0; /** - * @brief Obtains the directory for storing files for the application on the device's internal storage. - * - * @return Returns the application file directory. - */ + * @brief Obtains the directory for storing files for the application on the device's internal storage. + * + * @return Returns the application file directory. + */ virtual std::string GetFilesDir() = 0; /** - * @brief Checks whether the configuration of this ability is changing. - * - * @return Returns true if the configuration of this ability is changing and false otherwise. - */ + * @brief Checks whether the configuration of this ability is changing. + * + * @return Returns true if the configuration of this ability is changing and false otherwise. + */ virtual bool IsUpdatingConfigurations() = 0; /** - * @brief Informs the system of the time required for drawing this Page ability. - * - * @return Returns the notification is successful or fail - */ + * @brief Informs the system of the time required for drawing this Page ability. + * + * @return Returns the notification is successful or fail + */ virtual bool PrintDrawnCompleted() = 0; /** - * @brief Obtains the local database path. - * If the local database path does not exist, the system creates one and returns the created path. - * - * @return Returns the local database file. - */ + * @brief Obtains the local database path. + * If the local database path does not exist, the system creates one and returns the created path. + * + * @return Returns the local database file. + */ virtual std::string GetDatabaseDir() = 0; /** - * @brief Obtains the path storing the storage file of the application. - * - * @return Returns the local storage file. - */ + * @brief Obtains the local system database path. + * If the local system database path does not exist, the system creates one and returns the created path. + * + * @return Returns the local database file. + */ + virtual int32_t GetSystemDatabaseDir(const std::string &groupId, bool checkExist, std::string &databaseDir) = 0; + + /** + * @brief Obtains the path storing the storage file of the application. + * + * @return Returns the local storage file. + */ virtual std::string GetPreferencesDir() = 0; /** - * @brief Obtains the path distributed file of the application - * - * @return Returns the distributed file. - */ + * @brief Obtains the path storing the system storage file of the application. + * + * @return Returns the local system storage file. + */ + virtual int32_t GetSystemPreferencesDir(const std::string &groupId, bool checkExist, + std::string &preferencesDir) = 0; + + /** + * @brief Obtains the path storing the group file of the application by the groupId. + * + * @return Returns the local group file. + */ + virtual std::string GetGroupDir(std::string groupId) = 0; + + /** + * @brief Obtains the path distributed file of the application + * + * @return Returns the distributed file. + */ virtual std::string GetDistributedFilesDir() = 0; - /** - * @brief Obtains token. - * - * @return Returns the token. - */ + /** + * @brief Obtains token. + * + * @return Returns the token. + */ virtual sptr GetToken() = 0; /** - * @brief Attachs ability's token. - * - * @param token The token represents ability. - */ + * @brief Attachs ability's token. + * + * @param token The token represents ability. + */ virtual void SetToken(const sptr &token) = 0; /** - * @brief Switch file area - * - * @param mode file area. - */ + * @brief Switch file area + * + * @param mode file area. + */ virtual void SwitchArea(int mode) = 0; /** - * @brief Creates a Context object for a hap with the given module name. - * - * @param moduleName Indicates the module name of the hap. - * - * @return Returns a Context object created for the specified hap and app. - */ + * @brief Creates a Context object for a hap with the given module name. + * + * @param moduleName Indicates the module name of the hap. + * + * @return Returns a Context object created for the specified hap and app. + */ virtual std::shared_ptr CreateModuleContext(const std::string &moduleName) = 0; /** - * @brief Creates a Context object for a hap with the given hap name and app name. - * - * @param bundleName Indicates the app name of the application. - * - * @param moduleName Indicates the module name of the hap. - * - * @return Returns a Context object created for the specified hap and app. - */ + * @brief Creates a Context object for a hap with the given hap name and app name. + * + * @param bundleName Indicates the app name of the application. + * + * @param moduleName Indicates the module name of the hap. + * + * @return Returns a Context object created for the specified hap and app. + */ virtual std::shared_ptr CreateModuleContext(const std::string &bundleName, - const std::string &moduleName) = 0; + const std::string &moduleName) = 0; /** - * @brief Get file area - * - * @return file area. - */ + * @brief Get file area + * + * @return file area. + */ virtual int GetArea() = 0; /** - * @brief Obtains the configuration of application. - * - * @return configuration of application. - */ + * @brief Obtains the configuration of application. + * + * @return configuration of application. + */ virtual std::shared_ptr GetConfiguration() const = 0; /** - * @brief Obtains the application base directory on the device's internal storage. - * - * @return Returns the application base directory. - */ + * @brief Obtains the application base directory on the device's internal storage. + * + * @return Returns the application base directory. + */ virtual std::string GetBaseDir() const = 0; /** - * @brief Getting derived class - * - * @tparam T template - * @param context the context object - * @return std::shared_ptr derived class - */ + * @brief Obtains the Device Type. + * + * @return Returns the Device Type. + */ + virtual Global::Resource::DeviceType GetDeviceType() const = 0; + + /** + * @brief Getting derived class + * + * @tparam T template + * @param context the context object + * @return std::shared_ptr derived class + */ template - static std::shared_ptr ConvertTo(const std::shared_ptr& context) + static std::shared_ptr ConvertTo(const std::shared_ptr &context) { if constexpr (!std::is_same_v) { return nullptr; @@ -253,6 +283,6 @@ protected: static std::shared_ptr applicationContext_; static std::mutex contextMutex_; }; -} // namespace AbilityRuntime -} // namespace OHOS -#endif // ABILITY_RUNTIME_CONTEXT_H +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_STAGE_CONTEXT_CONTEXT_H diff --git a/mock/kits/ability/appkit/ability_runtime/context/context_impl.h b/mock/kits/ability/appkit/ability_runtime/context/context_impl.h index 33b7b970..96f93d4b 100644 --- a/mock/kits/ability/appkit/ability_runtime/context/context_impl.h +++ b/mock/kits/ability/appkit/ability_runtime/context/context_impl.h @@ -1,27 +1,29 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ABILITY_RUNTIME_CONTEXT_IMPL_H -#define ABILITY_RUNTIME_CONTEXT_IMPL_H +* Copyright (c) 2021-2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_ABILITY_RUNTIME_CONTEXT_IMPL_H +#define OHOS_ABILITY_RUNTIME_CONTEXT_IMPL_H -#include "context.h" - -#include "configuration.h" #include "bundle_mgr_interface.h" +#include "configuration.h" +#include "context.h" namespace OHOS { +namespace AppExecFwk { +struct RunningProcessInfo; +} namespace AbilityRuntime { class ContextImpl : public Context, public std::enable_shared_from_this { public: @@ -29,231 +31,273 @@ public: virtual ~ContextImpl() = default; /** - * @brief Obtains the bundle name of the current ability. - * - * @return Returns the bundle name of the current ability. - */ + * @brief Obtains the bundle name of the current ability. + * + * @return Returns the bundle name of the current ability. + */ std::string GetBundleName() const override; /** - * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, - * source code, and configuration files of a module. - * - * @return Returns the path of the package file. - */ + * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, + * source code, and configuration files of a module. + * + * @return Returns the path of the package file. + */ std::string GetBundleCodeDir() override; /** - * @brief Obtains the application-specific cache directory on the device's internal storage. The system - * automatically deletes files from the cache directory if disk space is required elsewhere on the device. - * Older files are always deleted first. - * - * @return Returns the application-specific cache directory. - */ + * @brief Obtains the application-specific cache directory on the device's internal storage. The system + * automatically deletes files from the cache directory if disk space is required elsewhere on the device. + * Older files are always deleted first. + * + * @return Returns the application-specific cache directory. + */ std::string GetCacheDir() override; /** - * @brief Checks whether the configuration of this ability is changing. - * - * @return Returns true if the configuration of this ability is changing and false otherwise. - */ + * @brief Checks whether the configuration of this ability is changing. + * + * @return Returns true if the configuration of this ability is changing and false otherwise. + */ bool IsUpdatingConfigurations() override; /** - * @brief Informs the system of the time required for drawing this Page ability. - * - * @return Returns the notification is successful or fail - */ + * @brief Informs the system of the time required for drawing this Page ability. + * + * @return Returns the notification is successful or fail + */ bool PrintDrawnCompleted() override; /** - * @brief Obtains the temporary directory. - * - * @return Returns the application temporary directory. - */ + * @brief Obtains the temporary directory. + * + * @return Returns the application temporary directory. + */ std::string GetTempDir() override; /** - * @brief Obtains the directory for storing files for the application on the device's internal storage. - * - * @return Returns the application file directory. - */ + * @brief Obtains the directory for storing files for the application on the device's internal storage. + * + * @return Returns the application file directory. + */ std::string GetFilesDir() override; /** - * @brief Obtains the local database path. - * If the local database path does not exist, the system creates one and returns the created path. - * - * @return Returns the local database file. - */ + * @brief Obtains the local database path. + * If the local database path does not exist, the system creates one and returns the created path. + * + * @return Returns the local database file. + */ std::string GetDatabaseDir() override; /** - * @brief Obtains the path storing the storage file of the application. - * - * @return Returns the local storage file. - */ + * @brief Obtains the local system database path. + * If the local group database path does not exist, the system creates one and returns the created path. + * + * @return Returns the local group database file. + */ + int32_t GetSystemDatabaseDir(const std::string &groupId, bool checkExist, std::string &databaseDir) override; + + /** + * @brief Obtains the path storing the storage file of the application. + * + * @return Returns the local storage file. + */ std::string GetPreferencesDir() override; /** - * @brief Obtains the path distributed file of the application - * - * @return Returns the distributed file. - */ + * @brief Obtains the path storing the system storage file of the application. + * + * @return Returns the local system storage file. + */ + int32_t GetSystemPreferencesDir(const std::string &groupId, bool checkExist, std::string &preferencesDir) override; + + /** + * @brief Obtains the path storing the group file of the application by the groupId. + * + * @return Returns the local group file. + */ + std::string GetGroupDir(std::string groupId) override; + + /** + * @brief Obtains the path distributed file of the application + * + * @return Returns the distributed file. + */ std::string GetDistributedFilesDir() override; /** - * @brief Switch file area - * - * @param mode file area. - */ + * @brief Switch file area + * + * @param mode file area. + */ void SwitchArea(int mode) override; /** - * @brief Creates a Context object for a hap with the given module name. - * - * @param moduleName Indicates the module name of the hap. - * - * @return Returns a Context object created for the specified hap and app. - */ + * @brief Creates a Context object for a hap with the given module name. + * + * @param moduleName Indicates the module name of the hap. + * + * @return Returns a Context object created for the specified hap and app. + */ std::shared_ptr CreateModuleContext(const std::string &moduleName) override; /** - * @brief Creates a Context object for a hap with the given hap name and app name. - * - * @param bundleName Indicates the app name of the application. - * - * @param moduleName Indicates the module name of the hap. - * - * @return Returns a Context object created for the specified hap and app. - */ + * @brief Creates a Context object for a hap with the given hap name and app name. + * + * @param bundleName Indicates the app name of the application. + * + * @param moduleName Indicates the module name of the hap. + * + * @return Returns a Context object created for the specified hap and app. + */ std::shared_ptr CreateModuleContext(const std::string &bundleName, const std::string &moduleName) override; /** - * @brief Get file area - * - * @return file area. - */ + * @brief Get file area + * + * @return file area. + */ int GetArea() override; /** - * @brief set the ResourceManager. - * - * @param the ResourceManager has been inited. - * - */ + * @brief set the ResourceManager. + * + * @param the ResourceManager has been initialized. + */ void SetResourceManager(const std::shared_ptr &resourceManager); /** - * @brief Obtains a resource manager. - * - * @return Returns a ResourceManager object. - */ + * @brief Obtains a resource manager. + * + * @return Returns a ResourceManager object. + */ std::shared_ptr GetResourceManager() const override; /** - * @brief Creates a Context object for an application with the given bundle name. - * - * @param bundleName Indicates the bundle name of the application. - * - * @return Returns a Context object created for the specified application. - */ + * @brief Creates a Context object for an application with the given bundle name. + * + * @param bundleName Indicates the bundle name of the application. + * + * @return Returns a Context object created for the specified application. + */ std::shared_ptr CreateBundleContext(const std::string &bundleName) override; /** - * @brief Obtains an IBundleMgr instance. - * You can use this instance to obtain information about the application bundle. - * - * @return Returns an IBundleMgr instance. - */ - sptr GetBundleManager() const; + * @brief Obtains an IBundleMgr instance. + * You can use this instance to obtain information about the application bundle. + * + * @return Returns an IBundleMgr instance. + */ + ErrCode GetBundleManager(); /** - * @brief Set ApplicationInfo - * - * @param info ApplicationInfo instance. - */ + * @brief Set ApplicationInfo + * + * @param info ApplicationInfo instance. + */ void SetApplicationInfo(const std::shared_ptr &info); /** - * @brief Obtains information about the current application. The returned application information includes basic - * information such as the application name and application permissions. - * - * @return Returns the ApplicationInfo for the current application. - */ + * @brief Obtains information about the current application. The returned application information includes basic + * information such as the application name and application permissions. + * + * @return Returns the ApplicationInfo for the current application. + */ std::shared_ptr GetApplicationInfo() const override; /** - * @brief Set ApplicationInfo - * - * @param info ApplicationInfo instance. - */ + * @brief Set ApplicationInfo + * + * @param info ApplicationInfo instance. + */ void SetParentContext(const std::shared_ptr &context); /** - * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, - * source code, and configuration files of a module. - * - * @return Returns the path of the package file. - */ + * @brief Obtains the path of the package containing the current ability. The returned path contains the resources, + * source code, and configuration files of a module. + * + * @return Returns the path of the package file. + */ std::string GetBundleCodePath() const override; /** - * @brief Obtains the HapModuleInfo object of the application. - * - * @return Returns the HapModuleInfo object of the application. - */ + * @brief Obtains the HapModuleInfo object of the application. + * + * @return Returns the HapModuleInfo object of the application. + */ std::shared_ptr GetHapModuleInfo() const override; /** - * @brief Set HapModuleInfo - * - * @param hapModuleInfo HapModuleInfo instance. - */ + * @brief Set HapModuleInfo + * + * @param hapModuleInfo HapModuleInfo instance. + */ void InitHapModuleInfo(const std::shared_ptr &abilityInfo); /** - * @brief Set HapModuleInfo - * - * @param hapModuleInfo HapModuleInfo instance. - */ + * @brief Set HapModuleInfo + * + * @param hapModuleInfo HapModuleInfo instance. + */ void InitHapModuleInfo(const AppExecFwk::HapModuleInfo &hapModuleInfo); /** - * @brief Set the token witch the app launched. - * - * @param token The token which the is launched by app. - */ + * @brief Set the token witch the app launched. + * + * @param token The token which the is launched by app. + */ void SetToken(const sptr &token) override; /** - * @brief Get the token witch the app launched. - * - * @return token The token which the is launched by app. - */ + * @brief Get the token witch the app launched. + * + * @return token The token which the is launched by app. + */ sptr GetToken() override; /** - * @brief Get the token witch the app launched. - * - * @return token The token which the is launched by app. - */ + * @brief Get the token witch the app launched. + * + * @return token The token which the is launched by app. + */ void SetConfiguration(const std::shared_ptr &config); /** - * @brief Get the token witch the app launched. - * - * @return token The token which the is launched by app. - */ + * @brief Kill process itself + * + * @return error code + */ + void KillProcessBySelf(); + + /** + * @brief Get running informationfor cuirrent process + * + * @return error code + */ + int32_t GetProcessRunningInformation(AppExecFwk::RunningProcessInfo &info); + + /** + * @brief Get the token witch the app launched. + * + * @return token The token which the is launched by app. + */ std::shared_ptr GetConfiguration() const override; /** - * @brief Obtains the application base directory on the device's internal storage. - * - * @return Returns the application base directory. - */ + * @brief Obtains the application base directory on the device's internal storage. + * + * @return Returns the application base directory. + */ std::string GetBaseDir() const override; + /** + * @brief Obtains the Device Type. + * + * @return Returns the Device Type. + */ + Global::Resource::DeviceType GetDeviceType() const override; + static const int EL_DEFAULT = 1; protected: @@ -273,6 +317,7 @@ private: static const std::string CONTEXT_PRIVATE; static const std::string CONTEXT_CACHE; static const std::string CONTEXT_PREFERENCES; + static const std::string CONTEXT_GROUP; static const std::string CONTEXT_DATABASE; static const std::string CONTEXT_TEMP; static const std::string CONTEXT_FILES; @@ -280,21 +325,53 @@ private: static const std::string CONTEXT_ELS[]; int flags_ = 0x00000000; - void InitResourceManager(const AppExecFwk::BundleInfo &bundleInfo, - const std::shared_ptr &appContext, bool currentBundle) const; + void InitResourceManager(const AppExecFwk::BundleInfo &bundleInfo, const std::shared_ptr &appContext, + bool currentBundle = false, const std::string &moduleName = ""); bool IsCreateBySystemApp() const; int GetCurrentAccountId() const; void SetFlags(int64_t flags); int GetCurrentActiveAccountId() const; - void CreateDirIfNotExist(const std::string& dirPath) const; - + void CreateDirIfNotExist(const std::string &dirPath, const mode_t &mode) const; + +// int GetOverlayModuleInfos(const std::string &bundleName, const std::string &moduleName, +// std::vector &overlayModuleInfos); +// +// void OnOverlayChanged(const EventFwk::CommonEventData &data, +// const std::shared_ptr &resourceManager, const std::string &bundleName, +// const std::string &moduleName, const std::string &loadPath); +// +// std::vector GetAddOverlayPaths(const std::vector &overlayModuleInfos); +// +// std::vector GetRemoveOverlayPaths( +// const std::vector &overlayModuleInfos); + + void ChangeToLocalPath(const std::string &bundleName, const std::string &sourcDir, std::string &localPath); + + void CreateDirIfNotExistWithCheck(const std::string &dirPath, const mode_t &mode, bool checkExist = true); + int32_t GetDatabaseDirWithCheck(bool checkExist, std::string &databaseDir); + int32_t GetGroupDatabaseDirWithCheck(const std::string &groupId, bool checkExist, std::string &databaseDir); + int32_t GetPreferencesDirWithCheck(bool checkExist, std::string &preferencesDir); + int32_t GetGroupPreferencesDirWithCheck(const std::string &groupId, bool checkExist, std::string &preferencesDir); + int32_t GetGroupDirWithCheck(const std::string &groupId, bool checkExist, std::string &groupDir); + + static Global::Resource::DeviceType deviceType_; std::shared_ptr applicationInfo_ = nullptr; std::shared_ptr parentContext_ = nullptr; std::shared_ptr resourceManager_ = nullptr; std::shared_ptr hapModuleInfo_ = nullptr; std::shared_ptr config_ = nullptr; std::string currArea_ = "el2"; +// std::vector overlayModuleInfos_; + std::set checkedDirSet_; + std::mutex checkedDirSetLock_; + + std::mutex bundleManagerMutex_; + sptr bundleMgr_; + + // True: need to get a new fms remote object, + // False: no need to get a new fms remote object. + volatile bool resetFlag_ = false; }; -} // namespace AbilityRuntime -} // namespace OHOS -#endif // ABILITY_RUNTIME_CONTEXT_IMPL_H +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_CONTEXT_IMPL_H diff --git a/mock/src/mock_aa_fwk.cpp b/mock/src/mock_aa_fwk.cpp index 2565d8e5..117f349c 100644 --- a/mock/src/mock_aa_fwk.cpp +++ b/mock/src/mock_aa_fwk.cpp @@ -17,6 +17,7 @@ #include "ability_connect_callback_stub.h" #include "dataobs_mgr_client.h" #include "data_ability_observer_stub.h" +#include "extension_manager_proxy.h" namespace OHOS::AAFwk { bool LaunchParam::ReadFromParcel(Parcel &parcel) { return false; } bool LaunchParam::Marshalling(Parcel &parcel) const { return false; } @@ -238,4 +239,24 @@ int DataAbilityObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } int DataAbilityObserverStub::OnChangeInner(MessageParcel &data, MessageParcel &reply) { return 0; } + +int ExtensionManagerProxy::ConnectAbilityCommon(const Want &want, const sptr &connect, + const sptr &callerToken, AppExecFwk::ExtensionAbilityType extensionType, int32_t userId) +{ + return IExtensionManager::ConnectAbilityCommon(want, connect, callerToken, extensionType, userId); +} +int ExtensionManagerProxy::DisconnectAbility(const sptr &connect) +{ + return 0; +} +bool ExtensionManagerProxy::WriteInterfaceToken(MessageParcel &data) +{ + return false; +} +ErrCode ExtensionManagerProxy::SendRequest(AbilityManagerInterfaceCode code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + return 0; +} } + diff --git a/mock/src/mock_access_token.cpp b/mock/src/mock_access_token.cpp index 1bb8e628..108332e9 100644 --- a/mock/src/mock_access_token.cpp +++ b/mock/src/mock_access_token.cpp @@ -15,7 +15,7 @@ #include "accesstoken_kit.h" #include "nativetoken_kit.h" #include "token_setproc.h" -static constexpr const char *BundleNames[60] = { +static constexpr const char *BundleNames[6] = { "invalid", "com.huawei.ohos.toteweather", "com.ohos.kvdatamanager.test", @@ -23,13 +23,13 @@ static constexpr const char *BundleNames[60] = { "ohos.test.demo1", "ohos.test.demo2" }; -static constexpr const char *AppId[60] = { +static constexpr const char *AppId[4] = { "invalid", "com.huawei.toteweather_adfasdflaskdfasdf", "", "ohos.test.demo_ABSEED" }; -static constexpr const char *NativeName[60] = { +static constexpr const char *NativeName[4] = { "invalid", "foundation", "distributed_test", @@ -67,17 +67,24 @@ int AccessTokenKit::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo &hapToke AccessTokenIDInner *inner = (AccessTokenIDInner *)&tokenID; hapTokenInfoRes.ver = 0; hapTokenInfoRes.userID = 100; - hapTokenInfoRes.instIndex = inner->tokenUniqueID / 60; + hapTokenInfoRes.instIndex = inner->tokenUniqueID & 1; hapTokenInfoRes.deviceID = "54a0a92a428005db27c40bad46bf145fede38ec37effe0347cd990fcb031f320"; hapTokenInfoRes.tokenID = tokenID; if (inner->type == TOKEN_NATIVE) { hapTokenInfoRes.apl = APL_SYSTEM_CORE; - hapTokenInfoRes.bundleName = NativeName[inner->tokenUniqueID % 60]; + if (inner->tokenUniqueID >= sizeof(NativeName) / sizeof(NativeName[0])) { + return -1; + } + hapTokenInfoRes.bundleName = NativeName[inner->tokenUniqueID % sizeof(NativeName) / sizeof(NativeName[0])]; hapTokenInfoRes.appID = hapTokenInfoRes.bundleName; } else { hapTokenInfoRes.apl = APL_NORMAL; - hapTokenInfoRes.bundleName = BundleNames[inner->tokenUniqueID % 60]; - hapTokenInfoRes.appID = AppId[inner->tokenUniqueID % 60]; + if (inner->tokenUniqueID >= sizeof(BundleNames) / sizeof(BundleNames[0]) || + inner->tokenUniqueID >= sizeof(AppId) / sizeof(AppId[0])) { + return -1; + } + hapTokenInfoRes.bundleName = BundleNames[inner->tokenUniqueID % sizeof(BundleNames)/sizeof(BundleNames[0])]; + hapTokenInfoRes.appID = AppId[inner->tokenUniqueID % sizeof(AppId)/sizeof(AppId[0])]; } return 0; } diff --git a/mock/src/mock_context.cpp b/mock/src/mock_context.cpp index fb866a81..36dcb593 100644 --- a/mock/src/mock_context.cpp +++ b/mock/src/mock_context.cpp @@ -61,7 +61,7 @@ int ContextImpl::GetArea() { return 0; } void ContextImpl::SetResourceManager(const std::shared_ptr &resourceManager) {} std::shared_ptr ContextImpl::GetResourceManager() const { return resourceManager_; } std::shared_ptr ContextImpl::CreateBundleContext(const std::string &bundleName) { return shared_from_this(); } -sptr ContextImpl::GetBundleManager() const { return sptr(); } +//sptr ContextImpl::GetBundleManager() const { return sptr(); } void ContextImpl::SetApplicationInfo( const std::shared_ptr &info) { applicationInfo_ = info; } std::shared_ptr ContextImpl::GetApplicationInfo() const { return applicationInfo_; } @@ -75,6 +75,75 @@ sptr ContextImpl::GetToken() { return token_; } void ContextImpl::SetConfiguration(const std::shared_ptr &config) {} std::shared_ptr ContextImpl::GetConfiguration() const { return config_; } std::string ContextImpl::GetBaseDir() const { return ""; } + +int32_t ContextImpl::GetSystemDatabaseDir(const std::string &groupId, bool checkExist, std::string &databaseDir) +{ + return 0; +} +int32_t ContextImpl::GetSystemPreferencesDir(const std::string &groupId, bool checkExist, std::string &preferencesDir) +{ + return 0; +} +std::string ContextImpl::GetGroupDir(std::string groupId) +{ + return std::string(); +} +ErrCode ContextImpl::GetBundleManager() +{ + return 0; +} +void ContextImpl::KillProcessBySelf() {} +int32_t ContextImpl::GetProcessRunningInformation(AppExecFwk::RunningProcessInfo &info) +{ + return 0; +} +Global::Resource::DeviceType ContextImpl::GetDeviceType() const +{ + return Global::Resource::DEVICE_CAR; +} +void ContextImpl::InitResourceManager(const AppExecFwk::BundleInfo &bundleInfo, + const std::shared_ptr &appContext, bool currentBundle, const std::string &moduleName) +{ +} +bool ContextImpl::IsCreateBySystemApp() const +{ + return false; +} +int ContextImpl::GetCurrentAccountId() const +{ + return 0; +} +void ContextImpl::SetFlags(int64_t flags) {} +int ContextImpl::GetCurrentActiveAccountId() const +{ + return 0; +} +void ContextImpl::CreateDirIfNotExist(const std::string &dirPath, const mode_t &mode) const {} +void ContextImpl::ChangeToLocalPath(const std::string &bundleName, const std::string &sourcDir, std::string &localPath) +{ +} +void ContextImpl::CreateDirIfNotExistWithCheck(const std::string &dirPath, const mode_t &mode, bool checkExist) {} +int32_t ContextImpl::GetDatabaseDirWithCheck(bool checkExist, std::string &databaseDir) +{ + return 0; +} +int32_t ContextImpl::GetGroupDatabaseDirWithCheck(const std::string &groupId, bool checkExist, std::string &databaseDir) +{ + return 0; +} +int32_t ContextImpl::GetPreferencesDirWithCheck(bool checkExist, std::string &preferencesDir) +{ + return 0; +} +int32_t ContextImpl::GetGroupPreferencesDirWithCheck(const std::string &groupId, bool checkExist, + std::string &preferencesDir) +{ + return 0; +} +int32_t ContextImpl::GetGroupDirWithCheck(const std::string &groupId, bool checkExist, std::string &groupDir) +{ + return 0; +} std::shared_ptr ExtensionContext::GetAbilityInfo() const { return abilityInfo_; } void ExtensionContext::SetAbilityInfo(const std::shared_ptr &abilityInfo) {} ExtensionModuleLoader& ExtensionModuleLoader::GetLoader(const char* sharedLibrary) { diff --git a/mock/src/mock_filemanagement.cpp b/mock/src/mock_filemanagement.cpp new file mode 100644 index 00000000..7cdc3c81 --- /dev/null +++ b/mock/src/mock_filemanagement.cpp @@ -0,0 +1,17 @@ +#include "remote_file_share.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +int RemoteFileShare::CreateSharePath(const int &fd, std::string &sharePath, const int &userId, + const std::string &deviceId) +{ + return 0; +} +int32_t RemoteFileShare::GetDfsUriFromLocal(const std::string &uriStr, const int32_t &userId, HmdfsUriInfo &hui) +{ + return 0; +} +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS \ No newline at end of file diff --git a/mock/src/mock_netmanager.cpp b/mock/src/mock_netmanager.cpp new file mode 100644 index 00000000..991320df --- /dev/null +++ b/mock/src/mock_netmanager.cpp @@ -0,0 +1,212 @@ +#include "net_conn_callback_stub.h" +#include "net_conn_client.h" +#include "net_handle.h" + +namespace OHOS{ +namespace NetManagerStandard{ + +int32_t NetHandle::BindSocket(int32_t socket_fd) +{ + return 0; +} +int32_t NetHandle::GetAddressesByName(const std::string &host, + std::vector &addrList) +{ + return 0; +} +int32_t NetHandle::GetAddressByName(const std::string &host, + OHOS::NetManagerStandard::INetAddr &addr) +{ + return 0; +} + +NetConnClient &NetConnClient::GetInstance() +{ + static NetConnClient netConnClient; + return netConnClient; +} + +int32_t NetConnClient::SystemReady() +{ + return 0; +} +int32_t NetConnClient::SetInternetPermission(uint32_t uid, uint8_t allow) +{ + return 0; +} +int32_t NetConnClient::RegisterNetSupplier(NetBearType bearerType, const std::string &ident, + const std::set &netCaps, uint32_t &supplierId) +{ + return 0; +} +int32_t NetConnClient::UnregisterNetSupplier(uint32_t supplierId) +{ + return 0; +} +int32_t NetConnClient::RegisterNetSupplierCallback(uint32_t supplierId, const sptr &callback) +{ + return 0; +} +int32_t NetConnClient::UpdateNetSupplierInfo(uint32_t supplierId, const sptr &netSupplierInfo) +{ + return 0; +} +int32_t NetConnClient::UpdateNetLinkInfo(uint32_t supplierId, const sptr &netLinkInfo) +{ + return 0; +} +int32_t NetConnClient::RegisterNetConnCallback(const sptr &callback) +{ + return 0; +} +int32_t NetConnClient::RegisterNetConnCallback(const sptr &netSpecifier, + const sptr &callback, const uint32_t &timeoutMS) +{ + return 0; +} +int32_t NetConnClient::UnregisterNetConnCallback(const sptr &callback) +{ + return 0; +} +int32_t NetConnClient::GetDefaultNet(NetHandle &netHandle) +{ + return 0; +} +int32_t NetConnClient::HasDefaultNet(bool &flag) +{ + return 0; +} +int32_t NetConnClient::GetAllNets(std::list> &netList) +{ + return 0; +} +int32_t NetConnClient::GetConnectionProperties(const NetHandle &netHandle, NetLinkInfo &info) +{ + return 0; +} +int32_t NetConnClient::GetNetCapabilities(const NetHandle &netHandle, NetAllCapabilities &netAllCap) +{ + return 0; +} +int32_t NetConnClient::GetAddressesByName(const std::string &host, int32_t netId, std::vector &addrList) +{ + return 0; +} +int32_t NetConnClient::GetAddressByName(const std::string &host, int32_t netId, INetAddr &addr) +{ + return 0; +} +int32_t NetConnClient::BindSocket(int32_t socket_fd, int32_t netId) +{ + return 0; +} +int32_t NetConnClient::NetDetection(const NetHandle &netHandle) +{ + return 0; +} +int32_t NetConnClient::SetAirplaneMode(bool state) +{ + return 0; +} +int32_t NetConnClient::IsDefaultNetMetered(bool &isMetered) +{ + return 0; +} +int32_t NetConnClient::SetGlobalHttpProxy(const HttpProxy &httpProxy) +{ + return 0; +} +int32_t NetConnClient::GetGlobalHttpProxy(HttpProxy &httpProxy) +{ + return 0; +} +int32_t NetConnClient::GetDefaultHttpProxy(HttpProxy &httpProxy) +{ + return 0; +} +int32_t NetConnClient::SetAppNet(int32_t netId) +{ + return 0; +} +int32_t NetConnClient::GetAppNet(int32_t &netId) +{ + return 0; +} +int32_t NetConnClient::GetNetIdByIdentifier(const std::string &ident, std::list &netIdList) +{ + return 0; +} +int32_t NetConnClient::RegisterNetInterfaceCallback(const sptr &callback) +{ + return 0; +} +int32_t NetConnClient::GetNetInterfaceConfiguration(const std::string &iface, NetInterfaceConfiguration &config) +{ + return 0; +} +NetConnClient::NetConnClient() {} +NetConnClient::~NetConnClient() {} +sptr NetConnClient::GetProxy() +{ + return sptr(); +} +void NetConnClient::OnRemoteDied(const wptr &remote) {} + +NetConnCallbackStub::~NetConnCallbackStub() {} +NetConnCallbackStub::NetConnCallbackStub() {} +int32_t NetConnCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} +int32_t NetConnCallbackStub::NetAvailable(sptr &netHandle) +{ + return 0; +} +int32_t NetConnCallbackStub::NetCapabilitiesChange(sptr &netHandle, + const sptr &netAllCap) +{ + return 0; +} +int32_t NetConnCallbackStub::NetConnectionPropertiesChange(sptr &netHandle, const sptr &info) +{ + return 0; +} +int32_t NetConnCallbackStub::NetLost(sptr &netHandle) +{ + return 0; +} +int32_t NetConnCallbackStub::NetUnavailable() +{ + return 0; +} +int32_t NetConnCallbackStub::NetBlockStatusChange(sptr &netHandle, bool blocked) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetAvailable(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetCapabilitiesChange(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetConnectionPropertiesChange(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetLost(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetUnavailable(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +int32_t NetConnCallbackStub::OnNetBlockStatusChange(MessageParcel &data, MessageParcel &reply) +{ + return 0; +} +} +} \ No newline at end of file diff --git a/mock/src/mock_notification.cpp b/mock/src/mock_notification.cpp index 0cbf4bce..5951fef5 100644 --- a/mock/src/mock_notification.cpp +++ b/mock/src/mock_notification.cpp @@ -197,7 +197,47 @@ const std::string CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED = "COMMON_EVE const std::string CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED = "COMMON_EVENT_PACKAGE_CHANGED"; const std::string CommonEventSupport::COMMON_EVENT_USER_SWITCHED = "COMMON_EVENT_USER_SWITCHED"; const std::string CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED = "COMMON_EVENT_SANDBOX_PACKAGE_REMOVED"; +const std::string CommonEventSupport::COMMON_EVENT_TIME_CHANGED = "COMMON_EVENT_TIME_CHANGED"; +const std::string CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED = "COMMON_EVENT_TIMEZONE_CHANGED"; bool CommonEventSubscribeInfo::Marshalling(OHOS::Parcel &) const { return true; } +CommonEventSubscribeInfo::CommonEventSubscribeInfo(const CommonEventSubscribeInfo &commonEventSubscribeInfo) {} +void CommonEventSubscribeInfo::SetPriority(const int32_t &priority) {} +int32_t CommonEventSubscribeInfo::GetPriority() const +{ + return 0; +} +void CommonEventSubscribeInfo::SetUserId(const int32_t &userId) {} +int32_t CommonEventSubscribeInfo::GetUserId() const +{ + return 0; +} +void CommonEventSubscribeInfo::SetPermission(const std::string &permission) {} +std::string CommonEventSubscribeInfo::GetPermission() const +{ + return std::string(); +} +CommonEventSubscribeInfo::ThreadMode CommonEventSubscribeInfo::GetThreadMode() const +{ + return CommonEventSubscribeInfo::ASYNC; +} +void CommonEventSubscribeInfo::SetThreadMode(CommonEventSubscribeInfo::ThreadMode threadMode) {} +void CommonEventSubscribeInfo::SetDeviceId(const std::string &deviceId) {} +std::string CommonEventSubscribeInfo::GetDeviceId() const +{ + return std::string(); +} +const MatchingSkills &CommonEventSubscribeInfo::GetMatchingSkills() const +{ + return matchingSkills_; +} +CommonEventSubscribeInfo *CommonEventSubscribeInfo::Unmarshalling(Parcel &parcel) +{ + return nullptr; +} +bool CommonEventSubscribeInfo::ReadFromParcel(Parcel &parcel) +{ + return false; +} bool CommonEventManager::SubscribeCommonEvent( std::shared_ptr const &) { return false; } bool CommonEventManager::PublishCommonEvent(OHOS::EventFwk::CommonEventData const &) { return false; } diff --git a/preferences/CMakeLists.txt b/preferences/CMakeLists.txt index 93ef4d80..f2ad819a 100644 --- a/preferences/CMakeLists.txt +++ b/preferences/CMakeLists.txt @@ -10,10 +10,12 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=0") set(MOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../mock) add_definitions(-DNAPI_EXPERIMENTAL) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/src preferences_src) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/common/src preferences_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/src preferences_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/common/src preferences_src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/inner_api/include) diff --git a/preferences/bundle.json b/preferences/bundle.json index 01965a6a..2966a2a6 100644 --- a/preferences/bundle.json +++ b/preferences/bundle.json @@ -38,7 +38,8 @@ "name": "preferences", "subsystem": "distributeddatamgr", "syscap": [ - "SystemCapability.DistributedDataManager.Preferences.Core" + "SystemCapability.DistributedDataManager.Preferences.Core", + "SystemCapability.DistributedDataManager.Preferences.Core.Lite" ], "features": [], "adapted_system_type": [ @@ -50,15 +51,16 @@ "components": [ "ability_runtime", "napi", - "hilog_native", + "hilog", "c_utils", "ability_base", "common_event_service", - "hitrace_native" + "hitrace", + "ipc" ], "third_party": [ "libxml2", - "gtest_main" + "googletest" ] }, "build": { @@ -86,6 +88,7 @@ "test": [ "//foundation/distributeddatamgr/preferences/test/native:unittest", "//foundation/distributeddatamgr/preferences/test/js:unittest", + "//foundation/distributeddatamgr/preferences/test/js:performancetest", "//foundation/distributeddatamgr/preferences/test/native/fuzztest/preferences_fuzzer:PreferencesFuzzTest" ] } diff --git a/preferences/frameworks/js/napi/common/include/js_ability.h b/preferences/frameworks/js/napi/common/include/js_ability.h index 6cd73314..0d5766da 100644 --- a/preferences/frameworks/js/napi/common/include/js_ability.h +++ b/preferences/frameworks/js/napi/common/include/js_ability.h @@ -26,21 +26,15 @@ namespace OHOS { namespace PreferencesJsKit { -class Context { -public: - explicit Context(std::shared_ptr stageContext); - explicit Context(std::shared_ptr abilityContext); - - std::string GetPreferencesDir(); - -private: - std::string preferencesDir_; +struct ContextInfo { + std::string bundleName; + std::string preferencesDir; }; - class JSAbility final { public: - static bool CheckContext(napi_env env, napi_callback_info info); - static std::shared_ptr GetContext(napi_env env, napi_value object); + static int GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo); + static napi_status IsStageContext(napi_env env, napi_value value, bool &isStageMode); }; } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/include/napi_async_call.h b/preferences/frameworks/js/napi/common/include/napi_async_call.h index 2f95ac03..1091538c 100644 --- a/preferences/frameworks/js/napi/common/include/napi_async_call.h +++ b/preferences/frameworks/js/napi/common/include/napi_async_call.h @@ -28,20 +28,20 @@ namespace OHOS { namespace PreferencesJsKit { -using InputAction = std::function; -using OutputAction = std::function; +using InputAction = std::function; +using OutputAction = std::function; using ExecuteAction = std::function; class BaseContext { public: void SetAction(napi_env env, napi_callback_info info, InputAction input, ExecuteAction exec, OutputAction output); - void SetError(std::shared_ptr error); + void SetError(std::shared_ptr error); virtual ~BaseContext(); napi_env env_ = nullptr; void *boundObj = nullptr; - int execStatus = ERR; - std::shared_ptr error; + int execCode_ = ERR; + std::shared_ptr error; napi_ref self_ = nullptr; napi_ref callback_ = nullptr; @@ -61,7 +61,7 @@ private: enum { ARG_ERROR, ARG_DATA, ARG_BUTT }; static void OnExecute(napi_env env, void *data); static void OnComplete(napi_env env, napi_status status, void *data); - static void SetBusinessError(napi_env env, napi_value *businessError, std::shared_ptr error); + static void SetBusinessError(napi_env env, napi_value *businessError, std::shared_ptr error); }; } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/include/napi_preferences_error.h b/preferences/frameworks/js/napi/common/include/napi_preferences_error.h index bda12b00..e7af3100 100644 --- a/preferences/frameworks/js/napi/common/include/napi_preferences_error.h +++ b/preferences/frameworks/js/napi/common/include/napi_preferences_error.h @@ -15,7 +15,10 @@ #ifndef PRE_JS_NAPI_ERROR_H #define PRE_JS_NAPI_ERROR_H +#include + #include "log_print.h" +#include "preferences_errno.h" namespace OHOS { namespace PreferencesJsKit { @@ -24,13 +27,21 @@ constexpr int OK = 0; constexpr int ERR = -1; constexpr int EXCEED_MAX_LENGTH = -2; -constexpr int E_PARAM_ERROR = 401; +constexpr int E_INVALID_PARAM = 401; constexpr int E_INNER_ERROR = 15500000; -constexpr int E_PREFERENCES_ERROR = 15500010; +constexpr int E_NOT_STAGE_MODE = 15501001; +constexpr int E_DATA_GROUP_ID_INVALID = 15501002; const static std::map ERROR_MAPS = { + { E_NOT_STAGE_MODE, "Only supported in stage mode" }, + { E_DATA_GROUP_ID_INVALID, "The data group id is not valid" }, + { NativePreferences::E_NOT_SUPPORTED, "Capability not supported" }, + { NativePreferences::E_GET_DATAOBSMGRCLIENT_FAIL, "Failed to obtain subscription service." }, + { NativePreferences::E_DELETE_FILE_FAIL, "Failed to delete preferences file." } }; +#define PRE_REVT_NOTHING + #define PRE_NAPI_ASSERT_BASE(env, assertion, error, retVal) \ do { \ if (!(assertion)) { \ @@ -47,52 +58,38 @@ const static std::map ERROR_MAPS = { #define PRE_NAPI_ASSERT_RETURN_VOID(env, assertion, error) \ PRE_NAPI_ASSERT_BASE(env, assertion, error, NAPI_RETVAL_NOTHING) -#define PRE_ASYNC_PARAM_CHECK_FUNCTION(theCall) \ - do { \ - int err = (theCall); \ - if (err != OK) { \ - return err; \ - } \ - } while (0) - -#define PRE_CHECK_RETURN_NULLPTR(context, assertion) \ - do { \ - if (!(assertion)) { \ - /* avoid cyclic dependence */ \ - (context)->exec_ = nullptr; \ - (context)->output_ = nullptr; \ - return nullptr; \ - } \ - } while (0) - -#define PRE_CHECK_RETURN(assertion, theCall) \ +#define PRE_CHECK_RETURN_CORE(assertion, theCall, revt) \ do { \ if (!(assertion)) { \ - (theCall); \ - return ERR; \ + theCall; \ + return revt; \ } \ } while (0) -#define PRE_CHECK_PARAM_NUM_VALID(assertion, errMsg) \ - do { \ - if (!(assertion)) { \ - std::shared_ptr paramNumError = std::make_shared(errMsg); \ - context->SetError(paramNumError); \ - return ERR; \ - } \ - } while (0) +#define PRE_CHECK_RETURN_VOID_SET(assertion, error) \ + PRE_CHECK_RETURN_CORE(assertion, context->SetError(error), PRE_REVT_NOTHING) + +#define PRE_CHECK_RETURN_ERR_SET(assertion, error) \ + PRE_CHECK_RETURN_CORE(assertion, context->SetError(error), ERR) + +#define PRE_CHECK_RETURN_NULL(assertion) \ + PRE_CHECK_RETURN_CORE(assertion, PRE_REVT_NOTHING, nullptr) + +#define PRE_CHECK_RETURN_VOID(assertion) \ + PRE_CHECK_RETURN_CORE(assertion, PRE_REVT_NOTHING, PRE_REVT_NOTHING) + +#define PRE_CHECK_RETURN_ERR(assertion) \ + PRE_CHECK_RETURN_CORE(assertion, PRE_REVT_NOTHING, ERR) -#define PRE_NAPI_ASSERT_RETURN_VOID(env, assertion, error) \ - PRE_NAPI_ASSERT_BASE(env, assertion, error, NAPI_RETVAL_NOTHING) -class Error { +class JSError { public: - virtual ~Error(){}; + virtual ~JSError(){}; virtual std::string GetMsg() = 0; virtual int GetCode() = 0; }; -class ParamTypeError : public Error { +class ParamTypeError : public JSError { public: ParamTypeError(const std::string &name, const std::string &wantType) : name(name), wantType(wantType){}; std::string GetMsg() override @@ -101,7 +98,7 @@ public: }; int GetCode() override { - return E_PARAM_ERROR; + return E_INVALID_PARAM; }; private: @@ -109,7 +106,7 @@ private: std::string wantType; }; -class InnerError : public Error { +class InnerError : public JSError { public: InnerError(int code) { @@ -137,7 +134,7 @@ private: std::string msg_; }; -class ParamNumError : public Error { +class ParamNumError : public JSError { public: ParamNumError(const std::string &wantNum) : wantNum(wantNum){}; std::string GetMsg() override @@ -146,29 +143,13 @@ public: }; int GetCode() override { - return E_PARAM_ERROR; + return E_INVALID_PARAM; }; private: std::string apiname; std::string wantNum; }; - -class DeleteError : public Error { -public: - DeleteError() = default; - std::string GetMsg() override - { - return "Failed to delete preferences file."; - }; - int GetCode() override - { - return E_PREFERENCES_ERROR; - }; - -private: - std::string apiname; -}; } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/mock/cross_platform/include/js_ability.h b/preferences/frameworks/js/napi/common/mock/cross_platform/include/js_ability.h index 03ee9aea..0d747982 100644 --- a/preferences/frameworks/js/napi/common/mock/cross_platform/include/js_ability.h +++ b/preferences/frameworks/js/napi/common/mock/cross_platform/include/js_ability.h @@ -26,20 +26,15 @@ namespace OHOS { namespace PreferencesJsKit { -class Context { -public: - explicit Context(std::shared_ptr stageContext); - - std::string GetPreferencesDir(); - -private: - std::string preferencesDir_; +struct ContextInfo { + std::string bundleName; + std::string preferencesDir; }; - class JSAbility final { public: - static bool CheckContext(napi_env env, napi_callback_info info); - static std::shared_ptr GetContext(napi_env env, napi_value object); + static int GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo); + static napi_status IsStageContext(napi_env env, napi_value value, bool &isStageMode); }; } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp b/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp index 23e8a620..e1322324 100644 --- a/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp +++ b/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp @@ -16,32 +16,29 @@ #include "js_ability.h" #include "log_print.h" +#include "napi_preferences_error.h" namespace OHOS { namespace PreferencesJsKit { -Context::Context(std::shared_ptr stageContext) +napi_status JSAbility::IsStageContext(napi_env env, napi_value value, bool &isStageMode) { - preferencesDir_ = stageContext->GetPreferencesDir(); + isStageMode = true; + return napi_ok; } -std::string Context::GetPreferencesDir() -{ - return preferencesDir_; -} - -bool JSAbility::CheckContext(napi_env env, napi_callback_info info) -{ - return true; -} - -std::shared_ptr JSAbility::GetContext(napi_env env, napi_value value) +int JSAbility::GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo) { + if (!dataGroupId.empty()) { + return NativePreferences::E_NOT_SUPPORTED; + } auto stageContext = AbilityRuntime::Platform::GetStageModeContext(env, value); if (stageContext == nullptr) { LOG_ERROR("GetStageModeContext failed."); - return nullptr; + return E_INVALID_PARAM; } - return std::make_shared(stageContext); + contextInfo.preferencesDir = stageContext->GetPreferencesDir(); + return OK; } } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/mock/include/js_ability.h b/preferences/frameworks/js/napi/common/mock/include/js_ability.h index faebbfe7..cfe975fb 100644 --- a/preferences/frameworks/js/napi/common/mock/include/js_ability.h +++ b/preferences/frameworks/js/napi/common/mock/include/js_ability.h @@ -24,20 +24,15 @@ namespace OHOS { namespace PreferencesJsKit { -class Context { -public: - explicit Context(); - - std::string GetPreferencesDir(); - -private: - std::string preferencesDir_; +struct ContextInfo { + std::string bundleName; + std::string preferencesDir; }; - class JSAbility final { public: - static bool CheckContext(napi_env env, napi_callback_info info); - static std::shared_ptr GetContext(napi_env env, napi_value object); + static int GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo); + static napi_status IsStageContext(napi_env env, napi_value value, bool &isStageMode); }; } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp b/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp index 213d1bf2..47ab8755 100644 --- a/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp +++ b/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp @@ -18,41 +18,38 @@ #include #include "log_print.h" +#include "napi_preferences_error.h" namespace OHOS { namespace PreferencesJsKit { -Context::Context() +napi_status JSAbility::IsStageContext(napi_env env, napi_value value, bool &isStageMode) { + isStageMode = true; + return napi_ok; +} + +int JSAbility::GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo) +{ + if (!dataGroupId.empty()) { + return NativePreferences::E_NOT_SUPPORTED; + } std::string baseDir = ""; #ifdef WINDOWS_PLATFORM baseDir = getenv("TEMP"); if (!baseDir.empty()) { - preferencesDir_ = baseDir + "\\HuaweiDevEcoStudioPreferences"; + contextInfo.preferencesDir = baseDir + "\\HuaweiDevEcoStudioPreferences"; } #endif #ifdef MAC_PLATFORM baseDir = getenv("LOGNAME"); - baseDir = "/Users/" + baseDir + "/Library/Caches"; if (!baseDir.empty()) { - preferencesDir_ = baseDir + "/HuaweiDevEcoStudioPreferences"; + baseDir = "/Users/" + baseDir + "/Library/Caches"; + contextInfo.preferencesDir = baseDir + "/HuaweiDevEcoStudioPreferences"; } #endif -} - -std::string Context::GetPreferencesDir() -{ - return preferencesDir_; -} - -bool JSAbility::CheckContext(napi_env env, napi_callback_info info) -{ - return true; -} - -std::shared_ptr JSAbility::GetContext(napi_env env, napi_value value) -{ - return std::make_shared(); + return OK; } } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/src/js_ability.cpp b/preferences/frameworks/js/napi/common/src/js_ability.cpp index ba8ffd7f..f27d3577 100644 --- a/preferences/frameworks/js/napi/common/src/js_ability.cpp +++ b/preferences/frameworks/js/napi/common/src/js_ability.cpp @@ -12,71 +12,55 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "js_ability.h" #include "extension_context.h" #include "log_print.h" +#include "napi_preferences_error.h" namespace OHOS { namespace PreferencesJsKit { -Context::Context(std::shared_ptr stageContext) -{ - preferencesDir_ = stageContext->GetPreferencesDir(); - auto extensionContext = AbilityRuntime::Context::ConvertTo(stageContext); - if (extensionContext != nullptr) { - auto abilityInfo = extensionContext->GetAbilityInfo(); - } -} - -Context::Context(std::shared_ptr abilityContext) +napi_status JSAbility::IsStageContext(napi_env env, napi_value value, bool &isStageMode) { - preferencesDir_ = abilityContext->GetPreferencesDir(); - auto abilityInfo = abilityContext->GetAbilityInfo(); + napi_status status = AbilityRuntime::IsStageContext(env, value, isStageMode); + return status; } -std::string Context::GetPreferencesDir() +int JSAbility::GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, const bool &isStageMode, + ContextInfo &contextInfo) { - return preferencesDir_; -} - -bool JSAbility::CheckContext(napi_env env, napi_callback_info info) -{ - size_t argc = 1; - napi_value args[1] = { 0 }; - bool mode = false; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - napi_status status = AbilityRuntime::IsStageContext(env, args[0], mode); - LOG_DEBUG("Check context as stage mode, mode is %{public}d, status is %{public}d", mode, status == napi_ok); - return status == napi_ok; -} - -std::shared_ptr JSAbility::GetContext(napi_env env, napi_value value) -{ - bool mode = false; - AbilityRuntime::IsStageContext(env, value, mode); - if (mode) { - LOG_DEBUG("Get context as stage mode."); + if (isStageMode) { auto stageContext = AbilityRuntime::GetStageModeContext(env, value); if (stageContext == nullptr) { - LOG_ERROR("GetStageModeContext failed."); - return nullptr; + LOG_ERROR("failed to get stage mode context."); + return E_INNER_ERROR; + } + + int errcode = stageContext->GetSystemPreferencesDir(dataGroupId, false, contextInfo.preferencesDir); + if (errcode != 0) { + return E_DATA_GROUP_ID_INVALID; } - return std::make_shared(stageContext); + contextInfo.bundleName = stageContext->GetBundleName(); + return OK; + } + + if (!dataGroupId.empty()) { + return E_NOT_STAGE_MODE; } - LOG_DEBUG("Get context as feature ability mode."); auto ability = AbilityRuntime::GetCurrentAbility(env); if (ability == nullptr) { - LOG_ERROR("GetCurrentAbility failed."); - return nullptr; + LOG_ERROR("failed to get current ability."); + return E_INNER_ERROR; } + auto abilityContext = ability->GetAbilityContext(); - if (abilityContext == nullptr) { - LOG_ERROR("GetAbilityContext failed."); - return nullptr; + if (ability == nullptr) { + LOG_ERROR("failed to get ability context."); + return E_INNER_ERROR; } - return std::make_shared(abilityContext); + abilityContext->GetSystemPreferencesDir("", false, contextInfo.preferencesDir); + return OK; } } // namespace PreferencesJsKit } // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/src/napi_async_call.cpp b/preferences/frameworks/js/napi/common/src/napi_async_call.cpp index 401b1115..8b2d1032 100644 --- a/preferences/frameworks/js/napi/common/src/napi_async_call.cpp +++ b/preferences/frameworks/js/napi/common/src/napi_async_call.cpp @@ -25,29 +25,33 @@ void BaseContext::SetAction( size_t argc = MAX_INPUT_COUNT; napi_value self = nullptr; napi_value argv[MAX_INPUT_COUNT] = { nullptr }; - NAPI_CALL_RETURN_VOID(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr)); - + napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); napi_valuetype valueType = napi_undefined; - if (argc > 0) { + if (status == napi_ok && argc > 0) { napi_typeof(env, argv[argc - 1], &valueType); if (valueType == napi_function) { - NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, argv[argc - 1], 1, &callback_)); + status = napi_create_reference(env, argv[argc - 1], 1, &callback_); argc = argc - 1; } } + // int -->input_(env, argc, argv, self) - int status = input(env, argc, argv, self); - + if (status == napi_ok) { + input(env, argc, argv, self); + } else { + error = std::make_shared(NativePreferences::E_ERROR); + } + // if input return is not ok, then napi_throw_error context error - PRE_NAPI_ASSERT_RETURN_VOID(env, status == OK, error); - + PRE_NAPI_ASSERT_RETURN_VOID(env, error == nullptr, error); + output_ = std::move(output); exec_ = std::move(exec); napi_create_reference(env, self, 1, &self_); } -void BaseContext::SetError(std::shared_ptr err) +void BaseContext::SetError(std::shared_ptr err) { error = err; } @@ -67,14 +71,13 @@ BaseContext::~BaseContext() env_ = nullptr; } -void AsyncCall::SetBusinessError(napi_env env, napi_value *businessError, std::shared_ptr error) +void AsyncCall::SetBusinessError(napi_env env, napi_value *businessError, std::shared_ptr error) { - LOG_DEBUG("SetBusinessError enter"); napi_value code = nullptr; napi_value msg = nullptr; napi_create_object(env, businessError); // if error is not inner error - if (error != nullptr && error->GetCode() != E_PARAM_ERROR) { + if (error != nullptr && error->GetCode() != E_INVALID_PARAM) { napi_create_int32(env, error->GetCode(), &code); napi_create_string_utf8(env, error->GetMsg().c_str(), NAPI_AUTO_LENGTH, &msg); napi_set_named_property(env, *businessError, "code", code); @@ -85,6 +88,7 @@ void AsyncCall::SetBusinessError(napi_env env, napi_value *businessError, std::s napi_value AsyncCall::Call(napi_env env, std::shared_ptr context) { napi_value promise = nullptr; + if (context->callback_ == nullptr) { napi_create_promise(env, &context->defer_, &promise); } else { @@ -105,22 +109,26 @@ void AsyncCall::OnExecute(napi_env env, void *data) { BaseContext *context = reinterpret_cast(data); if (context->exec_) { - context->execStatus = context->exec_(); + context->execCode_ = context->exec_(); } + context->exec_ = nullptr; } void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) { BaseContext *context = reinterpret_cast(data); + if (context->execCode_ != NativePreferences::E_OK) { + context->SetError(std::make_shared(context->execCode_)); + } napi_value output = nullptr; - int outStatus = ERR; // if async execute status is not napi_ok then un-execute out function - if ((context->execStatus == OK) && context->output_) { - outStatus = context->output_(env, output); + if ((context->error == nullptr) && context->output_) { + context->output_(env, output); } + context->output_ = nullptr; napi_value result[ARG_BUTT] = { 0 }; // if out function status is ok then async renturn output data, else return error. - if (outStatus == OK) { + if (context->error == nullptr) { napi_get_undefined(env, &result[ARG_ERROR]); if (output != nullptr) { result[ARG_DATA] = output; @@ -128,14 +136,12 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) napi_get_undefined(env, &result[ARG_DATA]); } } else { - napi_value businessError = nullptr; - SetBusinessError(env, &businessError, context->error); - result[ARG_ERROR] = businessError; + SetBusinessError(env, &result[ARG_ERROR], context->error); napi_get_undefined(env, &result[ARG_DATA]); } if (context->defer_ != nullptr) { // promise - if (status == napi_ok && outStatus == OK) { + if (status == napi_ok && (context->error == nullptr)) { napi_resolve_deferred(env, context->defer_, result[ARG_DATA]); } else { napi_reject_deferred(env, context->defer_, result[ARG_ERROR]); @@ -147,8 +153,6 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) napi_value returnValue; napi_call_function(env, nullptr, callback, ARG_BUTT, result, &returnValue); } - context->exec_ = nullptr; - context->output_ = nullptr; context->keep_.reset(); } } // namespace PreferencesJsKit diff --git a/preferences/frameworks/js/napi/preferences/BUILD.gn b/preferences/frameworks/js/napi/preferences/BUILD.gn index b42d7db1..db122862 100644 --- a/preferences/frameworks/js/napi/preferences/BUILD.gn +++ b/preferences/frameworks/js/napi/preferences/BUILD.gn @@ -50,7 +50,8 @@ if (is_ohos) { external_deps = [ "ability_runtime:abilitykit_native", "ability_runtime:napi_base_context", - "hilog_native:libhilog", + "c_utils:utils", + "hilog:libhilog", "napi:ace_napi", ] diff --git a/preferences/frameworks/js/napi/preferences/include/napi_preferences.h b/preferences/frameworks/js/napi/preferences/include/napi_preferences.h index fe50fcf2..326a5303 100644 --- a/preferences/frameworks/js/napi/preferences/include/napi_preferences.h +++ b/preferences/frameworks/js/napi/preferences/include/napi_preferences.h @@ -21,6 +21,7 @@ #include #include "js_observer.h" +#include "js_utils.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -30,6 +31,7 @@ namespace OHOS { namespace PreferencesJsKit { +using RegisterMode = NativePreferences::PreferencesObserver::RegisterMode; class PreferencesProxy { public: static void Init(napi_env env, napi_value exports); @@ -39,6 +41,8 @@ public: static void Destructor(napi_env env, void *nativeObject, void *finalize_hint); private: + static constexpr char STR_CHANGE[] = "change"; + static constexpr char STR_MULTI_PRECESS_CHANGE[] = "multiProcessChange"; explicit PreferencesProxy(); ~PreferencesProxy(); @@ -59,16 +63,17 @@ private: static napi_value ClearSync(napi_env env, napi_callback_info info); static napi_value GetAllSync(napi_env env, napi_callback_info info); - bool HasRegisteredObserver(napi_value callback); - void RegisteredObserver(napi_value callback); - void UnRegisteredObserver(napi_value callback); - void UnRegisteredAllObservers(); - + static RegisterMode ConvertToRegisterMode(const std::string &mode); + bool HasRegisteredObserver(napi_value callback, RegisterMode mode); + int RegisteredObserver(napi_value callback, RegisterMode mode); + int UnRegisteredObserver(napi_value callback, RegisterMode mode); + int UnRegisteredAllObservers(RegisterMode mode); std::shared_ptr value_; napi_env env_; std::mutex listMutex_ {}; - std::list> dataObserver_; + std::list> localObservers_; + std::list> multiProcessObservers_; std::shared_ptr uvQueue_; }; } // namespace PreferencesJsKit diff --git a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp index 2361dc4e..61217171 100644 --- a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp +++ b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp @@ -20,9 +20,8 @@ #include #include -#include "napi_async_call.h" #include "log_print.h" -#include "js_utils.h" +#include "napi_async_call.h" #include "napi_preferences_error.h" #include "preferences.h" #include "preferences_errno.h" @@ -60,10 +59,8 @@ PreferencesProxy::PreferencesProxy() PreferencesProxy::~PreferencesProxy() { - for (auto &observer : dataObserver_) { - value_->UnRegisterObserver(observer); - } - dataObserver_.clear(); + UnRegisteredAllObservers(RegisterMode::LOCAL_CHANGE); + UnRegisteredAllObservers(RegisterMode::MULTI_PRECESS_CHANGE); } void PreferencesProxy::Destructor(napi_env env, void *nativeObject, void *finalize_hint) @@ -116,13 +113,21 @@ napi_status PreferencesProxy::NewInstance( if (status != napi_ok) { return status; } - PreferencesProxy *proxy = nullptr; - status = napi_unwrap(env, *instance, reinterpret_cast(&proxy)); - if (proxy == nullptr || status != napi_ok) { - LOG_ERROR("PreferencesProxy::NewInstance unwarp native preferences is null"); - return napi_generic_failure; + + PreferencesProxy *obj = new (std::nothrow) PreferencesProxy(); + if (obj == nullptr) { + LOG_ERROR("PreferencesProxy::New new failed, obj is nullptr"); + return napi_invalid_arg; } - proxy->value_ = value; + obj->value_ = value; + obj->env_ = env; + obj->uvQueue_ = std::make_shared(env); + status = napi_wrap(env, *instance, obj, PreferencesProxy::Destructor, nullptr, nullptr); + if (status != napi_ok) { + delete obj; + return status; + } + return napi_ok; } @@ -134,34 +139,22 @@ napi_value PreferencesProxy::New(napi_env env, napi_callback_info info) LOG_WARN("get this failed"); return nullptr; } - PreferencesProxy *obj = new (std::nothrow) PreferencesProxy(); - if (obj == nullptr) { - LOG_ERROR("PreferencesProxy::New new failed, obj is nullptr"); - return nullptr; - } - obj->env_ = env; - obj->uvQueue_ = std::make_shared(env); - napi_status status = napi_wrap(env, thiz, obj, PreferencesProxy::Destructor, nullptr, nullptr); - if (status != napi_ok) { - delete obj; - return nullptr; - } return thiz; } int ParseKey(napi_env env, const napi_value arg, std::shared_ptr context) { int32_t rc = JSUtils::Convert2NativeValue(env, arg, context->key); - PRE_CHECK_RETURN(rc == napi_ok, context->SetError(std::make_shared("value", "string."))); - PRE_CHECK_RETURN(context->key.length() <= MAX_KEY_LENGTH, - context->SetError(std::make_shared("value", "less than 80 bytes."))); + PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("value", "string.")); + PRE_CHECK_RETURN_ERR_SET(context->key.length() <= MAX_KEY_LENGTH, + std::make_shared("value", "less than 80 bytes.")); return OK; } -int ParseDefValue(const napi_env &env, const napi_value &jsVal, std::shared_ptr context) +int ParseDefValue(const napi_env env, const napi_value jsVal, std::shared_ptr context) { int32_t rc = JSUtils::Convert2NativeValue(env, jsVal, context->defValue.value_); - PRE_CHECK_RETURN(rc == napi_ok, context->SetError(std::make_shared("value", "ValueType."))); + PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("value", "ValueType.")); return OK; } @@ -178,23 +171,21 @@ napi_value PreferencesProxy::GetAll(napi_env env, napi_callback_info info) { LOG_DEBUG("GetAll start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 0 || argc == 1, "0 or 1"); - + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); context->allElements = obj->value_->GetAll(); return OK; }; - auto output = [context](napi_env env, napi_value &result) -> int { - return GetAllExecute(env, context, result); + auto output = [context](napi_env env, napi_value &result) { + GetAllExecute(env, context, result); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -216,19 +207,18 @@ napi_value PreferencesProxy::GetValue(napi_env env, napi_callback_info info) { LOG_DEBUG("GetValue start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); napi_create_reference(env, argv[1], 1, &context->inputValueRef); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); context->defValue = obj->value_->Get(context->key, context->defValue); return OK; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { if (context->defValue.IsLong()) { LOG_DEBUG("GetValue get default value."); napi_get_reference_value(env, context->inputValueRef, &result); @@ -236,11 +226,11 @@ napi_value PreferencesProxy::GetValue(napi_env env, napi_callback_info info) result = JSUtils::Convert2JSValue(env, context->defValue.value_); } napi_delete_reference(env, context->inputValueRef); - return OK; + PRE_CHECK_RETURN_VOID_SET(result != nullptr, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -269,27 +259,24 @@ napi_value PreferencesProxy::SetValue(napi_env env, napi_callback_info info) { LOG_DEBUG("SetValue start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseDefValue(env, argv[1], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + PRE_CHECK_RETURN_VOID(ParseDefValue(env, argv[1], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { - int errCode; PreferencesProxy *obj = reinterpret_cast(context->boundObj); - errCode = obj->value_->Put(context->key, context->defValue); - return errCode; + return obj->value_->Put(context->key, context->defValue); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("SetValue end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -315,25 +302,23 @@ napi_value PreferencesProxy::Delete(napi_env env, napi_callback_info info) { LOG_DEBUG("Delete start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); - int errCode = obj->value_->Delete(context->key); - return (errCode == OK) ? OK : ERR; + return obj->value_->Delete(context->key); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("Delete end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -358,25 +343,24 @@ napi_value PreferencesProxy::HasKey(napi_env env, napi_callback_info info) { LOG_DEBUG("HasKey start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); context->hasKey = obj->value_->HasKey(context->key); return OK; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_boolean(env, context->hasKey, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("HasKey end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -400,23 +384,22 @@ napi_value PreferencesProxy::Flush(napi_env env, napi_callback_info info) { LOG_DEBUG("Flush start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 0 || argc == 1, "0 or 1"); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); return obj->value_->FlushSync(); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("Flush end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -424,23 +407,22 @@ napi_value PreferencesProxy::Clear(napi_env env, napi_callback_info info) { LOG_DEBUG("Clear start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 0 || argc == 1, "0 or 1"); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { PreferencesProxy *obj = reinterpret_cast(context->boundObj); return obj->value_->Clear(); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("Clear end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -467,18 +449,20 @@ napi_value PreferencesProxy::RegisterObserver(napi_env env, napi_callback_info i PRE_NAPI_ASSERT(env, argc == requireArgc, std::make_shared("2")); napi_valuetype type; NAPI_CALL(env, napi_typeof(env, args[0], &type)); - PRE_NAPI_ASSERT(env, type == napi_string, std::make_shared("type", "string 'change'.")); - - std::string chang; - int ret = JSUtils::Convert2NativeValue(env, args[0], chang); - PRE_NAPI_ASSERT(env, ret == OK && chang == "change", std::make_shared("type", "string 'change'.")); + PRE_NAPI_ASSERT(env, type == napi_string, + std::make_shared("registerMode", "string 'change or multiProcessChange'.")); + std::string registerMode; + JSUtils::Convert2NativeValue(env, args[0], registerMode); + PRE_NAPI_ASSERT(env, registerMode == STR_CHANGE || registerMode == STR_MULTI_PRECESS_CHANGE, + std::make_shared("registerMode", "string 'change or multiProcessChange'.")); NAPI_CALL(env, napi_typeof(env, args[1], &type)); PRE_NAPI_ASSERT(env, type == napi_function, std::make_shared("callback", "function type.")); PreferencesProxy *obj = nullptr; NAPI_CALL(env, napi_unwrap(env, thiz, reinterpret_cast(&obj))); - obj->RegisteredObserver(args[1]); + int errCode = obj->RegisteredObserver(args[1], ConvertToRegisterMode(registerMode)); + PRE_NAPI_ASSERT(env, errCode == OK, std::make_shared(errCode)); return nullptr; } @@ -495,11 +479,13 @@ napi_value PreferencesProxy::UnRegisterObserver(napi_env env, napi_callback_info napi_valuetype type; NAPI_CALL(env, napi_typeof(env, args[0], &type)); - PRE_NAPI_ASSERT(env, type == napi_string, std::make_shared("type", "string 'change'.")); + PRE_NAPI_ASSERT(env, type == napi_string, + std::make_shared("registerMode", "string change or multiProcessChange.")); - std::string chang; - int ret = JSUtils::Convert2NativeValue(env, args[0], chang); - PRE_NAPI_ASSERT(env, ret == OK && chang == "change", std::make_shared("type", "string 'change'.")); + std::string registerMode; + JSUtils::Convert2NativeValue(env, args[0], registerMode); + PRE_NAPI_ASSERT(env, registerMode == STR_CHANGE || registerMode == STR_MULTI_PRECESS_CHANGE, + std::make_shared("registerMode", "string change or multiProcessChange.")); if (argc == requireArgc) { NAPI_CALL(env, napi_typeof(env, args[1], &type)); @@ -509,19 +495,20 @@ napi_value PreferencesProxy::UnRegisterObserver(napi_env env, napi_callback_info PreferencesProxy *obj = nullptr; NAPI_CALL(env, napi_unwrap(env, thiz, reinterpret_cast(&obj))); - if (argc == requireArgc && type == napi_function) { - obj->UnRegisteredObserver(args[1]); + int errCode; + if (type == napi_function) { + errCode = obj->UnRegisteredObserver(args[1], ConvertToRegisterMode(registerMode)); } else { - obj->UnRegisteredAllObservers(); + errCode = obj->UnRegisteredAllObservers(ConvertToRegisterMode(registerMode)); } - + PRE_NAPI_ASSERT(env, errCode == OK, std::make_shared(errCode)); return nullptr; } -bool PreferencesProxy::HasRegisteredObserver(napi_value callback) +bool PreferencesProxy::HasRegisteredObserver(napi_value callback, RegisterMode mode) { - std::lock_guard lck(listMutex_); - for (auto &it : dataObserver_) { + auto &observers = (mode == RegisterMode::LOCAL_CHANGE) ? localObservers_ : multiProcessObservers_; + for (auto &it : observers) { if (JSUtils::Equals(env_, callback, it->GetCallback())) { LOG_INFO("The observer has already subscribed."); return true; @@ -530,39 +517,62 @@ bool PreferencesProxy::HasRegisteredObserver(napi_value callback) return false; } -void PreferencesProxy::RegisteredObserver(napi_value callback) +RegisterMode PreferencesProxy::ConvertToRegisterMode(const std::string &mode) { - if (!HasRegisteredObserver(callback)) { + return (mode == STR_CHANGE) ? RegisterMode::LOCAL_CHANGE : RegisterMode::MULTI_PRECESS_CHANGE; +} + +int PreferencesProxy::RegisteredObserver(napi_value callback, RegisterMode mode) +{ + std::lock_guard lck(listMutex_); + auto &observers = (mode == RegisterMode::LOCAL_CHANGE) ? localObservers_ : multiProcessObservers_; + if (!HasRegisteredObserver(callback, mode)) { auto observer = std::make_shared(uvQueue_, callback); - value_->RegisterObserver(observer); - dataObserver_.push_back(observer); - LOG_INFO("The observer subscribed success."); + int errCode = value_->RegisterObserver(observer, mode); + if (errCode != E_OK) { + return errCode; + } + observers.push_back(observer); } + LOG_INFO("The observer subscribed success."); + return E_OK; } -void PreferencesProxy::UnRegisteredObserver(napi_value callback) +int PreferencesProxy::UnRegisteredObserver(napi_value callback, RegisterMode mode) { std::lock_guard lck(listMutex_); - auto it = dataObserver_.begin(); - while (it != dataObserver_.end()) { + auto &observers = (mode == RegisterMode::LOCAL_CHANGE) ? localObservers_ : multiProcessObservers_; + auto it = observers.begin(); + while (it != observers.end()) { if (JSUtils::Equals(env_, callback, (*it)->GetCallback())) { - value_->UnRegisterObserver(*it); - it = dataObserver_.erase(it); + int errCode = value_->UnRegisterObserver(*it, mode); + if (errCode != E_OK) { + return errCode; + } + it = observers.erase(it); LOG_INFO("The observer unsubscribed success."); break; // specified observer is current iterator } ++it; } + return E_OK; } -void PreferencesProxy::UnRegisteredAllObservers() +int PreferencesProxy::UnRegisteredAllObservers(RegisterMode mode) { std::lock_guard lck(listMutex_); - auto it = dataObserver_.begin(); - while (it != dataObserver_.end()) { - value_->UnRegisterObserver(*it); - it = dataObserver_.erase(it); + auto &observers = (mode == RegisterMode::LOCAL_CHANGE) ? localObservers_ : multiProcessObservers_; + bool hasFailed = false; + int errCode = E_OK; + for (auto &observer : observers) { + errCode = value_->UnRegisterObserver(observer, mode); + if (errCode != E_OK) { + hasFailed = true; + LOG_ERROR("The observer unsubscribed has failed, errCode %{public}d.", errCode); + } } + observers.clear(); + return hasFailed ? E_ERROR : E_OK; LOG_INFO("All observers unsubscribed success."); } } // namespace PreferencesJsKit diff --git a/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp b/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp index db4fb98f..c137f6f1 100644 --- a/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp +++ b/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp @@ -16,139 +16,185 @@ #include -#include "napi_async_call.h" #include "js_ability.h" -#include "log_print.h" #include "js_utils.h" -#include "napi_preferences.h" +#include "log_print.h" +#include "napi_async_call.h" #include "napi_preferences_error.h" -#include "preferences.h" +#include "napi_preferences.h" #include "preferences_errno.h" +#include "preferences.h" #include "securec.h" using namespace OHOS::NativePreferences; namespace OHOS { namespace PreferencesJsKit { +constexpr const char* DATA_GROUP_ID = "dataGroupId"; +constexpr const char* NAME = "name"; + struct HelperAysncContext : public BaseContext { std::string path; - std::shared_ptr abilityContext; - std::shared_ptr proxy; - + std::string name; + std::string bundleName; + std::string dataGroupId; + std::shared_ptr proxy; + HelperAysncContext() { } virtual ~HelperAysncContext(){}; }; -int ParseContext(const napi_env &env, const napi_value &object, std::shared_ptr context) +int ParseName(const napi_env env, const napi_value name, std::shared_ptr context) { - LOG_DEBUG("ParseContext begin"); - auto abilityContext = JSAbility::GetContext(env, object); - PRE_CHECK_RETURN(abilityContext != nullptr, - context->SetError(std::make_shared("context", "a Context."))); - context->abilityContext = abilityContext; - LOG_DEBUG("ParseContext end"); + int status = JSUtils::Convert2NativeValue(env, name, context->name); + PRE_CHECK_RETURN_ERR_SET(status == OK && !context->name.empty(), + std::make_shared(NAME, "a without path non empty string.")); + size_t pos = context->name.find_first_of('/'); + PRE_CHECK_RETURN_ERR_SET(pos == std::string::npos, + std::make_shared(NAME, "a name string only without path.")); return OK; } -int ParseName(const napi_env &env, const napi_value &value, std::shared_ptr context) +int ParseGroupId(const napi_env env, const napi_value dataGroupId, std::shared_ptr context) { - LOG_DEBUG("ParseName start"); - std::string name; - int status = JSUtils::Convert2NativeValue(env, value, name); - PRE_CHECK_RETURN(status == OK || !name.empty(), - context->SetError(std::make_shared("name", "a without path non empty string."))); + int res = JSUtils::Convert2NativeValue(env, dataGroupId, context->dataGroupId); + PRE_CHECK_RETURN_ERR_SET(res == OK && !context->dataGroupId.empty(), + std::make_shared(DATA_GROUP_ID, "a non empty string.")); + return OK; +} + +int ParseParameters(const napi_env env, napi_value* argv, std::shared_ptr context) +{ + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[1], &valueType); + if (valueType == napi_string) { + PRE_CHECK_RETURN_ERR(ParseName(env, argv[1], context) == OK); + } else { + napi_value nameValue = nullptr; + napi_get_named_property(env, argv[1], NAME, &nameValue); + PRE_CHECK_RETURN_ERR(ParseName(env, nameValue, context) == OK); + bool hasDataGroupId = false; + napi_has_named_property(env, argv[1], DATA_GROUP_ID, &hasDataGroupId); + if (hasDataGroupId) { + napi_value dataGroupIdValue = nullptr; + napi_get_named_property(env, argv[1], DATA_GROUP_ID, &dataGroupIdValue); + PRE_CHECK_RETURN_ERR(ParseGroupId(env, dataGroupIdValue, context) == OK); + } + } + bool isStageMode = false; + napi_status status = JSAbility::IsStageContext(env, argv[0], isStageMode); + PRE_CHECK_RETURN_ERR_SET(status == napi_ok, std::make_shared("context", "a Context.")); - size_t pos = name.find_first_of('/'); - PRE_CHECK_RETURN(pos == std::string::npos, - context->SetError(std::make_shared("name", "a name string only without path."))); + ContextInfo contextInfo; + int errCode = JSAbility::GetContextInfo(env, argv[0], context->dataGroupId, isStageMode, contextInfo); + PRE_CHECK_RETURN_ERR_SET(errCode == OK, std::make_shared(errCode)); - std::string preferencesDir = context->abilityContext->GetPreferencesDir(); - context->path = preferencesDir.append("/").append(name); - return OK; + context->bundleName = contextInfo.bundleName; + context->path = contextInfo.preferencesDir.append("/").append(context->name); + return errCode; } napi_value GetPreferences(napi_env env, napi_callback_info info) { - LOG_DEBUG("GetPreferences start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseContext(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseName(env, argv[1], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); }; auto exec = [context]() -> int { int errCode = E_OK; - context->proxy = OHOS::NativePreferences::PreferencesHelper::GetPreferences(context->path, errCode); - LOG_DEBUG("GetPreferences return %{public}d", errCode); + Options options(context->path, context->bundleName, context->dataGroupId); + context->proxy = PreferencesHelper::GetPreferences(options, errCode); return errCode; }; - auto output = [context](napi_env env, napi_value &result) -> int { - napi_value path = nullptr; - napi_create_string_utf8(env, context->path.c_str(), NAPI_AUTO_LENGTH, &path); - auto ret = PreferencesProxy::NewInstance(env, context->proxy, &result); - LOG_DEBUG("GetPreferences end."); - return (ret == napi_ok) ? OK : ERR; + auto output = [context](napi_env env, napi_value &result) { + auto status = PreferencesProxy::NewInstance(env, context->proxy, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } +napi_value GetPreferencesSync(napi_env env, napi_callback_info info) +{ + napi_value self = nullptr; + size_t argc = 2; + napi_value argv[2] = { 0 }; + napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + PRE_NAPI_ASSERT(env, argc == 2, std::make_shared("2")); + + auto context = std::make_shared(); + PRE_NAPI_ASSERT(env, ParseParameters(env, argv, context) == OK, context->error); + + int errCode = ERR; + Options options(context->path, context->bundleName, context->dataGroupId); + auto proxy = PreferencesHelper::GetPreferences(options, errCode); + PRE_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + + napi_value result; + errCode = PreferencesProxy::NewInstance(env, proxy, &result); + + PRE_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + return result; +} + napi_value DeletePreferences(napi_env env, napi_callback_info info) { - LOG_DEBUG("DeletePreferences start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseContext(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseName(env, argv[1], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); }; auto exec = [context]() -> int { - int errCode = PreferencesHelper::DeletePreferences(context->path); - LOG_DEBUG("DeletePreferences execfunction return %{public}d", errCode); - PRE_CHECK_RETURN(errCode == E_OK, context->SetError(std::make_shared())); - - return (errCode == E_OK) ? OK : ERR; + return PreferencesHelper::DeletePreferences(context->path); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); - LOG_DEBUG("DeletePreferences end."); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } +napi_value DeletePreferencesSync(napi_env env, napi_callback_info info) +{ + napi_value self = nullptr; + size_t argc = 2; + napi_value argv[2] = { 0 }; + napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + PRE_NAPI_ASSERT(env, argc == 2, std::make_shared("2")); + + auto context = std::make_shared(); + PRE_NAPI_ASSERT(env, ParseParameters(env, argv, context) == OK, context->error); + int errCode = PreferencesHelper::DeletePreferences(context->path); + + PRE_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + return nullptr; +} + napi_value RemovePreferencesFromCache(napi_env env, napi_callback_info info) { - LOG_DEBUG("DeletePreferences start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseContext(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseName(env, argv[1], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); }; auto exec = [context]() -> int { - int errCode = PreferencesHelper::RemovePreferencesFromCache(context->path); - LOG_DEBUG("RemovePreferencesFromCache return %{public}d", errCode); - return (errCode == E_OK) ? OK : ERR; + return PreferencesHelper::RemovePreferencesFromCache(context->path); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); - LOG_DEBUG("RemovePreferencesFromCache end."); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -159,12 +205,9 @@ napi_value RemovePreferencesFromCacheSync(napi_env env, napi_callback_info info) napi_value argv[2] = { 0 }; napi_get_cb_info(env, info, &argc, argv, &self, nullptr); PRE_NAPI_ASSERT(env, argc == 2, std::make_shared("2")); - PreferencesProxy *proxy = nullptr; - napi_unwrap(env, self, reinterpret_cast(&proxy)); auto context = std::make_shared(); - PRE_NAPI_ASSERT(env, ParseContext(env, argv[0], context) == OK, context->error); - PRE_NAPI_ASSERT(env, ParseName(env, argv[1], context) == OK, context->error); + PRE_NAPI_ASSERT(env, ParseParameters(env, argv, context) == OK, context->error); int errCode = PreferencesHelper::RemovePreferencesFromCache(context->path); PRE_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); @@ -175,7 +218,9 @@ napi_value InitPreferencesHelper(napi_env env, napi_value exports) { napi_property_descriptor properties[] = { DECLARE_NAPI_FUNCTION("getPreferences", GetPreferences), + DECLARE_NAPI_FUNCTION("getPreferencesSync", GetPreferencesSync), DECLARE_NAPI_FUNCTION("deletePreferences", DeletePreferences), + DECLARE_NAPI_FUNCTION("deletePreferencesSync", DeletePreferencesSync), DECLARE_NAPI_FUNCTION("removePreferencesFromCache", RemovePreferencesFromCache), DECLARE_NAPI_FUNCTION("removePreferencesFromCacheSync", RemovePreferencesFromCacheSync), DECLARE_NAPI_PROPERTY("MAX_KEY_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_KEY_LENGTH)), diff --git a/preferences/frameworks/js/napi/storage/BUILD.gn b/preferences/frameworks/js/napi/storage/BUILD.gn index 7c4cfeba..80866979 100644 --- a/preferences/frameworks/js/napi/storage/BUILD.gn +++ b/preferences/frameworks/js/napi/storage/BUILD.gn @@ -47,7 +47,7 @@ if (!is_mingw && !is_mac) { [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] external_deps = [ - "hilog_native:libhilog", + "hilog:libhilog", "napi:ace_napi", ] diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp index 38f05e5e..abc9205b 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp @@ -252,13 +252,13 @@ napi_value StorageProxy::GetValueSync(napi_env env, napi_callback_info info) return output; } -int ParseKey(const napi_env &env, const napi_value &arg, std::shared_ptr asyncContext) +int ParseKey(const napi_env env, const napi_value arg, std::shared_ptr asyncContext) { napi_valuetype keyType = napi_undefined; napi_typeof(env, arg, &keyType); if (keyType != napi_string) { LOG_ERROR("ParseKey: key type must be string."); - std::shared_ptr paramError = std::make_shared("value", "string type."); + std::shared_ptr paramError = std::make_shared("value", "string type."); asyncContext->SetError(paramError); return ERR; } @@ -266,13 +266,13 @@ int ParseKey(const napi_env &env, const napi_value &arg, std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); return ERR; } if (keyBufferSize > MAX_KEY_LENGTH) { LOG_ERROR("the length of the key is over maximum length."); - std::shared_ptr paramError = std::make_shared("value", "less than 80 bytes."); + std::shared_ptr paramError = std::make_shared("value", "less than 80 bytes."); asyncContext->SetError(paramError); return ERR; } @@ -285,7 +285,7 @@ int ParseKey(const napi_env &env, const napi_value &arg, std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); delete[] key; return ERR; @@ -296,7 +296,7 @@ int ParseKey(const napi_env &env, const napi_value &arg, std::shared_ptr asyncContext) +int ParseDefValue(const napi_env env, const napi_value jsVal, std::shared_ptr asyncContext) { napi_valuetype valueType = napi_undefined; napi_typeof(env, jsVal, &valueType); @@ -304,7 +304,7 @@ int ParseDefValue(const napi_env &env, const napi_value &jsVal, std::shared_ptr< double number = 0.0; if (JSUtils::Convert2NativeValue(env, jsVal, number) != E_OK) { LOG_ERROR("ParseDefValue Convert2NativeValue error"); - std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); return ERR; } @@ -315,11 +315,12 @@ int ParseDefValue(const napi_env &env, const napi_value &jsVal, std::shared_ptr< if (ret != E_OK) { LOG_ERROR("ParseDefValue Convert2NativeValue error"); if (ret == EXCEED_MAX_LENGTH) { - std::shared_ptr paramError = std::make_shared("value", "less than 8192 bytes."); + std::shared_ptr paramError = + std::make_shared("value", "less than 8192 bytes."); asyncContext->SetError(paramError); return ERR; } - std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); return ERR; } @@ -328,14 +329,14 @@ int ParseDefValue(const napi_env &env, const napi_value &jsVal, std::shared_ptr< bool bValue = false; if (JSUtils::Convert2NativeValue(env, jsVal, bValue) != E_OK) { LOG_ERROR("ParseDefValue Convert2NativeValue error"); - std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); return ERR; } asyncContext->defValue = bValue; } else { LOG_ERROR("Wrong second parameter type"); - std::shared_ptr paramError = std::make_shared("value", "a ValueType."); + std::shared_ptr paramError = std::make_shared("value", "a ValueType."); asyncContext->SetError(paramError); return ERR; } @@ -346,12 +347,11 @@ napi_value StorageProxy::GetValue(napi_env env, napi_callback_info info) { LOG_DEBUG("GetValue start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseDefValue(env, argv[1], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + PRE_CHECK_RETURN_VOID(ParseDefValue(env, argv[1], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { int errCode = OK; @@ -371,7 +371,7 @@ napi_value StorageProxy::GetValue(napi_env env, napi_callback_info info) return errCode; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { int errCode = OK; if (context->defValue.IsBool()) { napi_get_boolean(context->env_, context->defValue, &result); @@ -383,12 +383,11 @@ napi_value StorageProxy::GetValue(napi_env env, napi_callback_info info) } else { errCode = ERR; } - - return errCode; + PRE_CHECK_RETURN_VOID_SET(errCode == OK, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -437,12 +436,11 @@ napi_value StorageProxy::SetValue(napi_env env, napi_callback_info info) { LOG_DEBUG("SetValue start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 2 || argc == 3, "2 or 3"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseDefValue(env, argv[1], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + PRE_CHECK_RETURN_VOID(ParseDefValue(env, argv[1], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { int errCode = OK; @@ -456,16 +454,15 @@ napi_value StorageProxy::SetValue(napi_env env, napi_callback_info info) } else { errCode = ERR; } - return errCode; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(context->env_, &result); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -495,24 +492,23 @@ napi_value StorageProxy::Delete(napi_env env, napi_callback_info info) { LOG_DEBUG("Delete start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { StorageProxy *obj = reinterpret_cast(context->boundObj); int errCode = obj->value_->Delete(context->key); return errCode; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(context->env_, &result); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -543,25 +539,24 @@ napi_value StorageProxy::HasKey(napi_env env, napi_callback_info info) { LOG_DEBUG("HasKeySync start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseKey(env, argv[0], context)); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { StorageProxy *obj = reinterpret_cast(context->boundObj); context->hasKey = obj->value_->HasKey(context->key); - + return OK; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_boolean(context->env_, context->hasKey, &result); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -569,23 +564,21 @@ napi_value StorageProxy::Flush(napi_env env, napi_callback_info info) { LOG_DEBUG("Flush start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 0 || argc == 1, "0 or 1"); - + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { StorageProxy *obj = reinterpret_cast(context->boundObj); return obj->value_->FlushSync(); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(context->env_, &result); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -618,23 +611,21 @@ napi_value StorageProxy::Clear(napi_env env, napi_callback_info info) { LOG_DEBUG("Flush start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 0 || argc == 1, "0 or 1"); - + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); napi_unwrap(env, self, &context->boundObj); - return OK; }; auto exec = [context]() -> int { StorageProxy *obj = reinterpret_cast(context->boundObj); return obj->value_->Clear(); }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(context->env_, &result); - return (status == napi_ok) ? OK : ERR; + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp index 2bf66614..1b20c793 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp @@ -51,7 +51,7 @@ napi_value GetStorageSync(napi_env env, napi_callback_info info) return instance; } -int ParseString(const napi_env &env, const napi_value &value, std::shared_ptr asyncContext) +int ParseString(const napi_env env, const napi_value value, std::shared_ptr asyncContext) { if (asyncContext == nullptr) { LOG_WARN("error input"); @@ -73,10 +73,9 @@ napi_value GetStorage(napi_env env, napi_callback_info info) { LOG_DEBUG("GetStorage start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK); }; auto exec = [context]() -> int { int errCode = E_OK; @@ -84,16 +83,16 @@ napi_value GetStorage(napi_env env, napi_callback_info info) LOG_DEBUG("GetPreferences return %{public}d", errCode); return errCode; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_value path = nullptr; napi_create_string_utf8(env, context->path.c_str(), NAPI_AUTO_LENGTH, &path); auto ret = StorageProxy::NewInstance(env, path, &result); + PRE_CHECK_RETURN_VOID_SET(ret == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("GetPreferences end."); - return (ret == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -146,27 +145,24 @@ napi_value DeleteStorage(napi_env env, napi_callback_info info) { LOG_DEBUG("DeletePreferences start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK); }; auto exec = [context]() -> int { int errCode = PreferencesHelper::DeletePreferences(context->path); LOG_DEBUG("DeletePreferences execfunction return %{public}d", errCode); - std::shared_ptr deleteError = std::make_shared(); - PRE_CHECK_RETURN(errCode == E_OK, context->SetError(deleteError)); - - return (errCode == E_OK) ? OK : ERR; + PRE_CHECK_RETURN_ERR_SET(errCode == E_OK, std::make_shared(errCode)); + return OK; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("DeletePreferences end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -193,24 +189,23 @@ napi_value RemoveStorageFromCache(napi_env env, napi_callback_info info) { LOG_DEBUG("RemovePreferencesFromCache start"); auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int { - PRE_CHECK_PARAM_NUM_VALID(argc == 1 || argc == 2, "1 or 2"); - PRE_ASYNC_PARAM_CHECK_FUNCTION(ParseString(env, argv[0], context)); - return OK; + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseString(env, argv[0], context) == OK); }; auto exec = [context]() -> int { int errCode = PreferencesHelper::RemovePreferencesFromCache(context->path); LOG_DEBUG("RemovePreferencesFromCache return %{public}d", errCode); return (errCode == E_OK) ? OK : ERR; }; - auto output = [context](napi_env env, napi_value &result) -> int { + auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared(E_ERROR)); LOG_DEBUG("RemovePreferencesFromCache end."); - return (status == napi_ok) ? OK : ERR; }; context->SetAction(env, info, input, exec, output); - PRE_CHECK_RETURN_NULLPTR(context, context->error == nullptr || context->error->GetCode() == OK); + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } diff --git a/preferences/frameworks/js/napi/system_storage/BUILD.gn b/preferences/frameworks/js/napi/system_storage/BUILD.gn index 63bce263..eb1f8a6b 100644 --- a/preferences/frameworks/js/napi/system_storage/BUILD.gn +++ b/preferences/frameworks/js/napi/system_storage/BUILD.gn @@ -46,7 +46,7 @@ if (!is_mingw && !is_mac) { "ability_runtime:abilitykit_native", "ability_runtime:napi_base_context", "common_event_service:cesfwk_innerkits", - "hilog_native:libhilog", + "hilog:libhilog", "napi:ace_napi", ] diff --git a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp index 638ec286..36689080 100644 --- a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp +++ b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp @@ -48,7 +48,15 @@ static constexpr uint32_t FAILCOUNT = 2; static constexpr uint32_t SUCCOUNT = 1; -void ParseString(napi_env env, napi_value &object, const char *name, const bool enable, std::string &output) +static constexpr int E_KEY_EMPTY_STSTEM_STORAGE = -1006; + +static constexpr int E_KEY_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE = -1016; + +static constexpr int E_VALUE_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE = -1017; + +static constexpr int E_DEFAULT_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE = -1018; + +void ParseString(napi_env env, napi_value object, const char *name, const bool enable, std::string &output) { napi_value value = nullptr; bool exist = false; @@ -61,7 +69,7 @@ void ParseString(napi_env env, napi_value &object, const char *name, const bool } } -void ParseFunction(napi_env env, napi_value &object, const char *name, napi_ref &output) +void ParseFunction(napi_env env, napi_value object, const char *name, napi_ref &output) { napi_value value = nullptr; bool exist = false; @@ -75,7 +83,7 @@ void ParseFunction(napi_env env, napi_value &object, const char *name, napi_ref } } -const std::string GetMessageInfo(int errCode) +const std::string GetMessageInfo(const int &errCode) { switch (errCode) { case E_KEY_EMPTY: @@ -91,6 +99,22 @@ const std::string GetMessageInfo(int errCode) } } +int32_t ConversionToSysStorageErrorCode(const int &errCode) +{ + switch (errCode) { + case E_KEY_EMPTY: + return E_KEY_EMPTY_STSTEM_STORAGE; + case E_KEY_EXCEED_LENGTH_LIMIT: + return E_KEY_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE; + case E_VALUE_EXCEED_LENGTH_LIMIT: + return E_VALUE_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE; + case E_DEFAULT_EXCEED_LENGTH_LIMIT: + return E_DEFAULT_EXCEED_LENGTH_LIMIT_STSTEM_STORAGE; + default: + return errCode; + } +} + void Complete(napi_env env, napi_status status, void *data) { AsyncContext *ctx = static_cast(data); @@ -117,7 +141,7 @@ void Complete(napi_env env, napi_status status, void *data) std::string message = GetMessageInfo(ctx->output); len = message.size(); NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, message.c_str(), len, &failRes[0])); - NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, ctx->output, &failRes[1])); + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, ConversionToSysStorageErrorCode(ctx->output), &failRes[1])); napi_value failCallbackResult = nullptr; NAPI_CALL_RETURN_VOID( env, napi_call_function(env, nullptr, failCallBack, FAILCOUNT, failRes, &failCallbackResult)); @@ -142,8 +166,9 @@ void Complete(napi_env env, napi_status status, void *data) std::string GetPrefName(napi_env env) { - auto ctx = JSAbility::GetContext(env, nullptr); - return ctx->GetPreferencesDir() + "/default.xml"; + ContextInfo contextInfo; + JSAbility::GetContextInfo(env, nullptr, "", false, contextInfo); + return contextInfo.preferencesDir + "/default.xml"; } napi_value Operate(napi_env env, napi_callback_info info, const char *resource, bool parseStrFlag, diff --git a/preferences/frameworks/native/common/include/data_preferences_observer_stub.h b/preferences/frameworks/native/common/include/data_preferences_observer_stub.h new file mode 100644 index 00000000..65248ad9 --- /dev/null +++ b/preferences/frameworks/native/common/include/data_preferences_observer_stub.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H +#define PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H + +#include "data_ability_observer_stub.h" +#include "dataobs_mgr_client.h" +#include "preferences_observer.h" + +namespace OHOS { +namespace NativePreferences { +using DataObsMgrClient = AAFwk::DataObsMgrClient; +class DataPreferencesObserverStub : public AAFwk::DataAbilityObserverStub { +public: + DataPreferencesObserverStub(const std::shared_ptr preferencesObserver); + + virtual ~DataPreferencesObserverStub(); + + void OnChange() override; + + void OnChangePreferences(const std::string &key) override; + +public: + std::weak_ptr preferencesObserver_; +}; +} // End of namespace NativePreferences +} // End of namespace OHOS +#endif // End of #ifndef PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H diff --git a/preferences/frameworks/native/common/mock/include/data_preferences_observer_stub.h b/preferences/frameworks/native/common/mock/include/data_preferences_observer_stub.h new file mode 100644 index 00000000..9d8dad4e --- /dev/null +++ b/preferences/frameworks/native/common/mock/include/data_preferences_observer_stub.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H +#define PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H + +#include +#include + +#include "preferences_observer.h" + +namespace OHOS { +class Uri { +public: + Uri(const std::string str) + { + } +}; +template +using sptr = std::shared_ptr; +namespace NativePreferences { + +class DataPreferencesObserverStub { +public: + DataPreferencesObserverStub(const std::shared_ptr preferencesObserver); + virtual ~DataPreferencesObserverStub(); + void OnChange(); + void OnChangePreferences(const std::string &key); +public: + std::weak_ptr preferencesObserver_; +}; + +class DataObsMgrClient { +public: + static std::shared_ptr GetInstance(); + DataObsMgrClient(); + ~DataObsMgrClient(); + int RegisterObserver(const Uri &uri, sptr dataObserver); + int UnregisterObserver(const Uri &uri, sptr dataObserver); + int NotifyChange(const Uri &uri); +private: + static std::mutex mutex_; + static std::shared_ptr instance_; +}; +} // End of namespace NativePreferences +} // End of namespace OHOS +#endif // End of #ifndef PREFERENCES_DATA_PREFERENCES_OBSERVER_STUB_H diff --git a/preferences/frameworks/native/common/mock/src/data_preferences_observer_stub.cpp b/preferences/frameworks/native/common/mock/src/data_preferences_observer_stub.cpp new file mode 100644 index 00000000..d40ca47b --- /dev/null +++ b/preferences/frameworks/native/common/mock/src/data_preferences_observer_stub.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "data_preferences_observer_stub.h" + +#include "preferences_errno.h" + +namespace OHOS { +namespace NativePreferences { +std::shared_ptr DataObsMgrClient::instance_ = nullptr; +std::mutex DataObsMgrClient::mutex_; + +DataPreferencesObserverStub::DataPreferencesObserverStub(const std::shared_ptr preferencesObserver) + : preferencesObserver_(preferencesObserver) +{ +} + +DataPreferencesObserverStub::~DataPreferencesObserverStub() +{ +} + +void DataPreferencesObserverStub::OnChange() +{ +} + +void DataPreferencesObserverStub::OnChangePreferences(const std::string &key) +{ + std::shared_ptr sharedPreferencesObserver = preferencesObserver_.lock(); + if (sharedPreferencesObserver != nullptr) { + sharedPreferencesObserver->OnChange(key); + } +} + +DataObsMgrClient::DataObsMgrClient() +{ +} + +DataObsMgrClient::~DataObsMgrClient() +{ +} + +std::shared_ptr DataObsMgrClient::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard lock(mutex_); + if (instance_ == nullptr) { + instance_ = std::make_shared(); + } + } + return instance_; +} + +int DataObsMgrClient::RegisterObserver(const Uri &uri, sptr dataObserver) +{ + return E_NOT_SUPPORTED; +} + +int DataObsMgrClient::UnregisterObserver(const Uri &uri, sptr dataObserver) +{ + return E_NOT_SUPPORTED; +} + +int DataObsMgrClient::NotifyChange(const Uri &uri) +{ + return E_NOT_SUPPORTED; +} +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/common/mock/src/filelock.cpp b/preferences/frameworks/native/common/mock/src/filelock.cpp new file mode 100644 index 00000000..e77be769 --- /dev/null +++ b/preferences/frameworks/native/common/mock/src/filelock.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "filelock.h" +namespace OHOS { +namespace NativePreferences { + +FileLock::FileLock() +{ + fd_ = -1; +} + +FileLock::~FileLock() +{ +} + +int FileLock::TryLock(const std::string &fileName) +{ + return E_OK; +} + +int FileLock::UnLock() +{ + return E_OK; +} +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/common/mock/src/preferences_thread.cpp b/preferences/frameworks/native/common/mock/src/preferences_thread.cpp new file mode 100644 index 00000000..e65bc5d0 --- /dev/null +++ b/preferences/frameworks/native/common/mock/src/preferences_thread.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "preferences_thread.h" +namespace OHOS { +namespace NativePreferences { +int PthreadSetNameNp(const std::string name) +{ + return pthread_setname_np(name.c_str()); +} +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/common/src/data_preferences_observer_stub.cpp b/preferences/frameworks/native/common/src/data_preferences_observer_stub.cpp new file mode 100644 index 00000000..f7754704 --- /dev/null +++ b/preferences/frameworks/native/common/src/data_preferences_observer_stub.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "data_preferences_observer_stub.h" + +namespace OHOS { +namespace NativePreferences { +DataPreferencesObserverStub::DataPreferencesObserverStub( + const std::shared_ptr preferencesObserver) : preferencesObserver_(preferencesObserver) +{ +} + +DataPreferencesObserverStub::~DataPreferencesObserverStub() +{ +} + +void DataPreferencesObserverStub::OnChange() +{ +} + +void DataPreferencesObserverStub::OnChangePreferences(const std::string &key) +{ + std::shared_ptr sharedPreferencesObserver = preferencesObserver_.lock(); + if (sharedPreferencesObserver != nullptr) { + sharedPreferencesObserver->OnChange(key); + } +} +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/include/adaptor.h b/preferences/frameworks/native/include/adaptor.h index 859c5e0d..b69ef0a6 100644 --- a/preferences/frameworks/native/include/adaptor.h +++ b/preferences/frameworks/native/include/adaptor.h @@ -26,6 +26,7 @@ #define DO_NOTHING #ifdef WINDOWS_PLATFORM +#include #include #include #define REALPATH(filePath, realPath, ...) (_fullpath(realPath, filePath, ##__VA_ARGS__)) @@ -33,7 +34,7 @@ #define ACCESS(filePath) (_access(filePath, FILE_EXIST)) #define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING -#elif MAC_PLATFORM +#elif defined(MAC_PLATFORM) #include #include #include @@ -42,7 +43,7 @@ #define ACCESS(filePath) (access(filePath, FILE_EXIST)) #define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING -#elif ANDROID_PLATFORM || IOS_PLATFORM +#elif defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM) #include #include #include @@ -60,7 +61,7 @@ #define REALPATH(filePath, realPath, ...) (realpath(filePath, realPath)) #define MKDIR(filePath) (mkdir(filePath, FILE_MODE)) #define ACCESS(filePath) (access(filePath, FILE_EXIST)) -#define DISTRIBUTED_DATA_HITRACE(trace) HiTrace hitrace(trace) +#define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING // HiTrace hitrace(trace) #endif diff --git a/preferences/frameworks/native/include/executor.h b/preferences/frameworks/native/include/executor.h new file mode 100644 index 00000000..5bee28c2 --- /dev/null +++ b/preferences/frameworks/native/include/executor.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_FRAMEWORKS_EXECUTOR_H +#define PREFERENCES_FRAMEWORKS_EXECUTOR_H +#include +#include +#include +#include + +#include "preferences_thread.h" +#include "priority_queue.h" +namespace OHOS { +namespace NativePreferences { + +class Executor : public std::enable_shared_from_this { +public: + using TaskId = uint64_t; + using Task = std::function; + using Duration = std::chrono::steady_clock::duration; + using Time = std::chrono::steady_clock::time_point; + static constexpr Time INVALID_TIME = std::chrono::time_point(); + static constexpr Duration INVALID_INTERVAL = std::chrono::milliseconds(0); + static constexpr uint64_t UNLIMITED_TIMES = std::numeric_limits::max(); + static constexpr Duration INVALID_DELAY = std::chrono::seconds(0); + static constexpr TaskId INVALID_TASK_ID = static_cast(0l); + + enum Status { + RUNNING, + IS_STOPPING, + STOPPED + }; + struct InnerTask { + std::function exec = []() {}; + Duration interval = INVALID_INTERVAL; + uint64_t times = UNLIMITED_TIMES; + TaskId taskId = INVALID_TASK_ID; + InnerTask() = default; + + bool Valid() const + { + return taskId != INVALID_TASK_ID; + } + }; + + Executor(const std::string &name) + : thread_([this, name] { + auto realName = std::string("task_queue_") + name; + PthreadSetNameNp(realName); + Run(); + self_ = nullptr; + }) + { + thread_.detach(); + } + + Executor() + : thread_([this] { + PthreadSetNameNp("Executor"); + Run(); + self_ = nullptr; + }) + { + thread_.detach(); + } + + void Bind(PriorityQueue *queue, std::function)> idle, + std::function, bool)> release) + { + std::unique_lock lock(mutex_); + self_ = shared_from_this(); + waits_ = queue; + idle_ = std::move(idle); + release_ = std::move(release); + condition_.notify_one(); + } + + void Stop(bool wait = false) noexcept + { + std::unique_lock lock(mutex_); + running_ = IS_STOPPING; + condition_.notify_one(); + cond_.wait(lock, [this, wait]() { return !wait || running_ == STOPPED; }); + } + +private: + static constexpr Duration TIME_OUT = std::chrono::seconds(2); + void Run() + { + std::unique_lock lock(mutex_); + do { + do { + condition_.wait(lock, [this] { + return running_ == IS_STOPPING || waits_ != nullptr; + }); + while (running_ == RUNNING && waits_ != nullptr && waits_->Size() > 0) { + auto currentTask = waits_->Pop(); + lock.unlock(); + currentTask.exec(); + lock.lock(); + waits_->Finish(currentTask.taskId); + } + if (!idle_(self_) && running_ == RUNNING) { + continue; + } + waits_ = nullptr; + } while (running_ == RUNNING && + condition_.wait_until(lock, std::chrono::steady_clock::now() + TIME_OUT, [this]() { + return waits_ != nullptr; + })); + } while (!release_(self_, running_ == IS_STOPPING)); + running_ = STOPPED; + cond_.notify_all(); + } + + Status running_ = RUNNING; + std::mutex mutex_; + std::condition_variable condition_; + std::condition_variable cond_; + std::shared_ptr self_; + PriorityQueue *waits_ = nullptr; + std::function)> idle_; + std::function, bool)> release_; + std::thread thread_; +}; +} // namespace NativePreferences +} // namespace OHOS +#endif // PREFERENCES_FRAMEWORKS_EXECUTOR_H \ No newline at end of file diff --git a/preferences/frameworks/native/include/executor_pool.h b/preferences/frameworks/native/include/executor_pool.h new file mode 100644 index 00000000..b2e11532 --- /dev/null +++ b/preferences/frameworks/native/include/executor_pool.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_FRAMEWORKS_EXECUTOR_POOL_H +#define PREFERENCES_FRAMEWORKS_EXECUTOR_POOL_H +#include +#include +#include +#include +#include + +#include "executor.h" +#include "pool.h" +#include "priority_queue.h" + + +namespace OHOS { +namespace NativePreferences { +class ExecutorPool { +public: + using TaskId = Executor::TaskId; + using Task = Executor::Task; + using Duration = Executor::Duration; + using Time = Executor::Time; + using InnerTask = Executor::InnerTask; + using Status = Executor::Status; + using TaskQueue = PriorityQueue; + static constexpr Time INVALID_TIME = std::chrono::time_point(); + static constexpr Duration INVALID_INTERVAL = std::chrono::milliseconds(0); + static constexpr uint64_t UNLIMITED_TIMES = std::numeric_limits::max(); + static constexpr Duration INVALID_DELAY = std::chrono::seconds(0); + static constexpr TaskId INVALID_TASK_ID = static_cast(0l); + + ExecutorPool(size_t max, size_t min) + : pool_(max, min), delayTasks_(InnerTask(), NextTimer), taskId_(INVALID_TASK_ID) + { + // When max equals 1, timer thread schedules and executes tasks. + if (max > 1) { + execs_ = new (std::nothrow) TaskQueue(InnerTask()); + } + } + + ~ExecutorPool() + { + poolStatus = Status::IS_STOPPING; + if (execs_ != nullptr) { + execs_->Clean(); + } + delayTasks_.Clean(); + std::shared_ptr scheduler; + { + std::lock_guard scheduleLock(mtx_); + scheduler = std::move(scheduler_); + } + if (scheduler != nullptr) { + scheduler->Stop(true); + } + pool_.Clean([](std::shared_ptr executor) { + executor->Stop(true); + }); + delete execs_; + poolStatus = Status::STOPPED; + } + + TaskId Execute(Task task) + { + if (poolStatus != Status::RUNNING) { + return INVALID_TASK_ID; + } + + if (execs_ == nullptr) { + return Schedule(std::move(task), INVALID_DELAY, INVALID_INTERVAL, UNLIMITED_TIMES); + } + + return Execute(std::move(task), GenTaskId()); + } + + TaskId Schedule(Duration delay, Task task) + { + return Schedule(std::move(task), delay, INVALID_INTERVAL, 1); + } + + TaskId Schedule(Task task, Duration interval) + { + return Schedule(std::move(task), INVALID_DELAY, interval, UNLIMITED_TIMES); + } + + TaskId Schedule(Task task, Duration delay, Duration interval) + { + return Schedule(std::move(task), delay, interval, UNLIMITED_TIMES); + } + + TaskId Schedule(Task task, Duration delay, Duration interval, uint64_t times) + { + InnerTask innerTask; + innerTask.exec = std::move(task); + innerTask.interval = interval; + innerTask.times = times; + innerTask.taskId = GenTaskId(); + return Schedule(std::move(innerTask), std::chrono::steady_clock::now() + delay); + } + + bool Remove(TaskId taskId, bool wait = false) + { + bool res = true; + auto delay = delayTasks_.Find(taskId); + if (!delay.Valid()) { + res = false; + } + delayTasks_.Remove(taskId, wait); + if (execs_ != nullptr) { + execs_->Remove(taskId, wait); + } + return res; + } + + TaskId Reset(TaskId taskId, Duration interval) + { + auto updated = delayTasks_.Update(taskId, [interval](InnerTask &task) -> std::pair { + if (task.interval != INVALID_INTERVAL) { + task.interval = interval; + } + auto time = std::chrono::steady_clock::now() + interval; + return std::pair{ true, time }; + }); + return updated ? taskId : INVALID_TASK_ID; + } + +private: + TaskId Execute(Task task, TaskId taskId) + { + InnerTask innerTask; + innerTask.exec = task; + innerTask.taskId = taskId; + execs_->Push(std::move(innerTask), taskId, INVALID_TIME); + auto executor = pool_.Get(); + if (executor == nullptr) { + return taskId; + } + executor->Bind( + execs_, + [this](std::shared_ptr exe) { + pool_.Idle(exe); + return true; + }, + [this](std::shared_ptr exe, bool force) -> bool { + return pool_.Release(exe, force); + }); + return taskId; + } + + TaskId Schedule(InnerTask innerTask, Time delay) + { + auto id = innerTask.taskId; + if (execs_ != nullptr) { + auto func = innerTask.exec; + auto run = [this, func, id]() { + Execute(func, id); + }; + innerTask.exec = run; + } + delayTasks_.Push(std::move(innerTask), id, delay); + std::lock_guard scheduleLock(mtx_); + if (scheduler_ == nullptr) { + scheduler_ = pool_.Get(true); + scheduler_->Bind( + &delayTasks_, + [this](std::shared_ptr exe) { + std::unique_lock lock(mtx_); + if (delayTasks_.Size() != 0) { + return false; + } + scheduler_ = nullptr; + pool_.Idle(exe); + return true; + }, + [this](std::shared_ptr exe, bool force) -> bool { + return pool_.Release(exe, force); + }); + } + return innerTask.taskId; + } + + TaskId GenTaskId() + { + auto taskId = ++taskId_; + if (taskId == INVALID_TASK_ID) { + taskId = ++taskId_; + } + return taskId; + } + + static std::pair NextTimer(InnerTask &task) + { + if (task.interval != INVALID_INTERVAL && --task.times > 0) { + auto time = std::chrono::steady_clock::now() + task.interval; + return { true, time }; + } + return { false, INVALID_TIME }; + } + + Status poolStatus = Status::RUNNING; + std::mutex mtx_; + Pool pool_; + TaskQueue delayTasks_; + std::shared_ptr scheduler_ = nullptr; + TaskQueue *execs_ = nullptr; + std::atomic taskId_; +}; +} // namespace NativePreferences +} // namespace OHOS + +#endif // PREFERENCES_FRAMEWORKS_EXECUTOR_POOL_H \ No newline at end of file diff --git a/preferences/frameworks/native/include/filelock.h b/preferences/frameworks/native/include/filelock.h new file mode 100644 index 00000000..743f3aa8 --- /dev/null +++ b/preferences/frameworks/native/include/filelock.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_FILE_LOCK_H +#define PREFERENCES_FILE_LOCK_H + +#include +#include +#include "preferences_errno.h" +namespace OHOS { +namespace NativePreferences { +class FileLock final { +public: + FileLock(); + ~FileLock(); + int TryLock(const std::string &fileName); + int UnLock(); +private: + int fd_{ -1 }; +}; +} // namespace NativePreferences +} // namespace OHOS +#endif \ No newline at end of file diff --git a/preferences/frameworks/native/include/pool.h b/preferences/frameworks/native/include/pool.h new file mode 100644 index 00000000..2eeda7c8 --- /dev/null +++ b/preferences/frameworks/native/include/pool.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_FRAMEWORKS_POOL_H +#define PREFERENCES_FRAMEWORKS_POOL_H +#include +#include +namespace OHOS { +namespace NativePreferences { + +template +class Pool { +public: + Pool(uint32_t capability, uint32_t min) : capability_(capability), min_(min) {} + + std::shared_ptr Get(bool isForce = false) + { + std::unique_lock lock(mutex_); + if (idle_ == nullptr) { + if (!isForce && current_ >= capability_) { + return nullptr; + } + auto cur = new Node(); + idle_ = cur; + current_++; + } + Node *cur = idle_; + idle_ = idle_->next; + if (idle_ != nullptr) { + idle_->prev = nullptr; + } + cur->next = busy_; + if (busy_ != nullptr) { + cur->prev = busy_->prev; + busy_->prev = cur; + } + busy_ = cur; + return cur->data; + }; + + int32_t Release(std::shared_ptr data, bool force = false) + { + std::unique_lock lock(mutex_); + Node *cur = idle_; + if (!force && current_ <= min_) { + return false; + } + while (cur != nullptr) { + if (cur->data == data) { + if (cur->next != nullptr) { + cur->next->prev = cur->prev; + } + if (cur->prev != nullptr) { + cur->prev->next = cur->next; + } + if (idle_ == cur) { + idle_ = cur->next; + } + current_--; + delete cur; + return true; + } else { + cur = cur->next; + continue; + } + } + return false; + } + + void Idle(std::shared_ptr data) + { + std::unique_lock lock(mutex_); + Node *cur = busy_; + while (cur != nullptr && cur->data != data) { + cur = cur->next; + } + if (cur == nullptr) { + return; + } + if (cur == busy_) { + busy_ = busy_->next; + } + if (cur->next != nullptr) { + cur->next->prev = cur->prev; + } + if (cur->prev != nullptr) { + cur->prev->next = cur->next; + } + cur->prev = nullptr; + cur->next = idle_; + if (idle_ != nullptr) { + idle_->prev = cur; + } + idle_ = cur; + } + + int32_t Clean(std::function)> close) noexcept + { + auto temp = min_; + min_ = 0; + while (busy_ != nullptr) { + close(busy_->data); + } + while (idle_ != nullptr) { + close(idle_->data); + } + min_ = temp; + return true; + } + +private: + struct Node { + Node *prev = nullptr; + Node *next = nullptr; + std::shared_ptr data = std::make_shared(); + }; + + uint32_t capability_; + uint32_t min_; + uint32_t current_ = 0; + Node *idle_ = nullptr; + Node *busy_ = nullptr; + std::mutex mutex_; +}; +} // namespace NativePreferences +} // namespace OHOS + +#endif // PREFERENCES_FRAMEWORKS_POOL_H diff --git a/preferences/frameworks/native/include/preferences_impl.h b/preferences/frameworks/native/include/preferences_impl.h index 64c7f9d6..1245f60f 100644 --- a/preferences/frameworks/native/include/preferences_impl.h +++ b/preferences/frameworks/native/include/preferences_impl.h @@ -29,14 +29,33 @@ #include "preferences.h" #include "preferences_observer.h" #include "preferences_value.h" +#include "executor_pool.h" + +#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM) +#include "data_preferences_observer_stub.h" +#else +namespace OHOS { +template class sptr; +class Uri; +} // namespace OHOS +#endif namespace OHOS { namespace NativePreferences { + +class DataPreferencesObserverStub; + +static const char *STR_BROKEN = ".broken"; +static const char *STR_BACKUP = ".bak"; +static const char *STR_LOCK = ".lock"; +static const char *STR_QUERY = "?"; +static const char *STR_SLASH = "/"; +static const char *STR_SCHEME = "sharepreferences://"; class PreferencesImpl : public Preferences, public std::enable_shared_from_this { public: - static std::shared_ptr GetPreferences(const std::string &path) + static std::shared_ptr GetPreferences(const Options &options) { - return std::shared_ptr(new PreferencesImpl(path)); + return std::shared_ptr(new PreferencesImpl(options)); } virtual ~PreferencesImpl(); @@ -142,14 +161,13 @@ public: int FlushSync() override; - void RegisterObserver(std::shared_ptr preferencesObserver) override; + int RegisterObserver(std::shared_ptr preferencesObserver, RegisterMode mode) override; - void UnRegisterObserver(std::shared_ptr preferencesObserver) override; + int UnRegisterObserver(std::shared_ptr preferencesObserver, RegisterMode mode) override; - static std::string MakeBackupPath(const std::string &prefPath); - static std::string MakeBrokenPath(const std::string &prefPath); + static std::string MakeFilePath(const std::string &prefPath, const std::string &suffix); private: - explicit PreferencesImpl(const std::string &path); + explicit PreferencesImpl(const Options &options); class MemoryToDiskRequest { public: MemoryToDiskRequest(const std::map &writeToDiskMap, @@ -166,7 +184,7 @@ private: std::mutex reqMutex_; std::condition_variable reqCond_; std::list keysModified_; - std::vector> preferencesObservers_; + std::vector> localObservers_; int writeToDiskResult_; bool wasWritten_; @@ -177,6 +195,7 @@ private: bool StartLoadFromDisk(); int CheckKey(const std::string &key); int CheckStringValue(const std::string &value); + Uri MakeUri(const std::string &key = ""); /* thread function */ static void LoadFromDisk(std::shared_ptr pref); @@ -197,13 +216,13 @@ private: std::mutex mutex_; std::condition_variable cond_; - std::vector> preferencesObservers_; + std::vector> localObservers_; + std::vector> multiProcessObservers_; std::map map_; std::list modifiedKeys_; + static ExecutorPool executorPool_; - const std::string filePath_; - const std::string backupPath_; - const std::string brokenPath_; + const Options options_; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/include/preferences_thread.h b/preferences/frameworks/native/include/preferences_thread.h new file mode 100644 index 00000000..26bee1e4 --- /dev/null +++ b/preferences/frameworks/native/include/preferences_thread.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_THREAD_H +#define PREFERENCES_THREAD_H + +#include + +#include +namespace OHOS { +namespace NativePreferences { +int PthreadSetNameNp(const std::string name); +} // End of namespace NativePreferences +} // End of namespace OHOS +#endif // End of #ifndef PREFERENCES_THREAD_H \ No newline at end of file diff --git a/preferences/frameworks/native/include/priority_queue.h b/preferences/frameworks/native/include/priority_queue.h new file mode 100644 index 00000000..6248c6e0 --- /dev/null +++ b/preferences/frameworks/native/include/priority_queue.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_PRIORITY_QUEUE_H +#define PREFERENCES_PRIORITY_QUEUE_H +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace NativePreferences { +template +class PriorityQueue { +public: + struct PQMatrix { + _Tsk task_; + _Tid id_; + PQMatrix(_Tsk task, _Tid id) : task_(task), id_(id) {} + }; + using TskIndex = typename std::map<_Tme, PQMatrix>::iterator; + using TskUpdater = typename std::function(_Tsk &element)>; + + PriorityQueue(const _Tsk &task, TskUpdater updater = nullptr) + : INVALID_TSK(std::move(task)), updater_(std::move(updater)) + { + if (!updater_) { + updater_ = [](_Tsk &) { return std::pair{false, _Tme()};}; + } + } + _Tsk Pop() + { + std::unique_lock lock(pqMtx_); + while (!tasks_.empty()) { + auto waitTme = tasks_.begin()->first; + if (waitTme > std::chrono::steady_clock::now()) { + popCv_.wait_until(lock, waitTme); + continue; + } + auto temp = tasks_.begin(); + auto id = temp->second.id_; + running_.emplace(id, temp->second); + auto res = std::move(temp->second.task_); + tasks_.erase(temp); + indexes_.erase(id); + return res; + } + return INVALID_TSK; + } + + bool Push(_Tsk tsk, _Tid id, _Tme tme) + { + std::unique_lock lock(pqMtx_); + if (!tsk.Valid()) { + return false; + } + auto temp = tasks_.emplace(tme, PQMatrix(std::move(tsk), id)); + indexes_.emplace(id, temp); + popCv_.notify_all(); + return true; + } + + size_t Size() + { + std::lock_guard lock(pqMtx_); + return tasks_.size(); + } + + _Tsk Find(_Tid id) + { + std::unique_lock lock(pqMtx_); + if (indexes_.find(id) != indexes_.end()) { + return indexes_[id]->second.task_; + } + return INVALID_TSK; + } + + bool Update(_Tid id, TskUpdater updater) + { + std::unique_lock lock(pqMtx_); + auto index = indexes_.find(id); + if (index != indexes_.end()) { + auto [updated, time] = updater(index->second->second.task_); + if (!updated) { + return false; + } + auto matrix = std::move(index->second->second); + tasks_.erase(index->second); + index->second = tasks_.emplace(time, std::move(matrix)); + popCv_.notify_all(); + return true; + } + + auto running = running_.find(id); + if (running != running_.end()) { + auto [updated, time] = updater((*running).second.task_); + return updated; + } + + return false; + } + + bool Remove(_Tid id, bool wait) + { + std::unique_lock lock(pqMtx_); + removeCv_.wait(lock, [this, id, wait] { + return !wait || running_.find(id) == running_.end(); + }); + auto index = indexes_.find(id); + if (index == indexes_.end()) { + return false; + } + tasks_.erase(index->second); + indexes_.erase(index); + popCv_.notify_all(); + return true; + } + + void Clean() + { + std::unique_lock lock(pqMtx_); + indexes_.clear(); + tasks_.clear(); + popCv_.notify_all(); + } + + void Finish(_Tid id) + { + std::unique_lock lock(pqMtx_); + auto it = running_.find(id); + if (it == running_.end()) { + return; + } + auto [repeat, time] = updater_(it->second.task_); + if (repeat) { + indexes_.emplace(id, tasks_.emplace(time, std::move(it->second))); + } + running_.erase(it); + removeCv_.notify_all(); + } + +private: + const _Tsk INVALID_TSK; + std::mutex pqMtx_; + std::condition_variable popCv_; + std::condition_variable removeCv_; + std::multimap<_Tme, PQMatrix> tasks_; + std::map<_Tid, PQMatrix> running_; + std::map<_Tid, TskIndex> indexes_; + TskUpdater updater_; +}; +} //namespace NativePreferences +} // namespace OHOS +#endif //PREFERENCES_PRIORITY_QUEUE_H \ No newline at end of file diff --git a/preferences/frameworks/native/src/filelock.cpp b/preferences/frameworks/native/src/filelock.cpp new file mode 100644 index 00000000..bfe0291a --- /dev/null +++ b/preferences/frameworks/native/src/filelock.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "filelock.h" + +#include +#include +#include + +#include +#include +#include + +#include "log_print.h" +namespace OHOS { +namespace NativePreferences { +static const std::chrono::microseconds WAIT_CONNECT_TIMEOUT(20); +static const int ATTEMPTS = 5; +FileLock::FileLock() +{ +} + +FileLock::~FileLock() +{ + if (fd_ > 0) { + close(fd_); + } +} + +int FileLock::TryLock(const std::string &fileName) +{ + int fd = open(fileName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (fd == -1) { + LOG_ERROR("Couldn't open file %{public}s errno %{public}d.", fileName.c_str(), errno); + return (errno == EACCES) ? PERMISSION_DENIED : E_ERROR; + } + struct flock fileLockInfo = { 0 }; + fileLockInfo.l_type = F_WRLCK; + fileLockInfo.l_whence = SEEK_SET; + fileLockInfo.l_start = 0; + fileLockInfo.l_len = 0; + + for (size_t i = 0; i < ATTEMPTS; ++i) { + if (fcntl(fd, F_SETLK, &fileLockInfo) != -1) { + fd_ = fd; + return E_OK; + } + std::this_thread::sleep_for(WAIT_CONNECT_TIMEOUT); + } + close(fd); + return E_ERROR; +} + +int FileLock::UnLock() +{ + int errCode = E_OK; + if (fd_ > 0) { + struct flock fileLockInfo = { 0 }; + fileLockInfo.l_type = F_UNLCK; + fileLockInfo.l_whence = SEEK_SET; + fileLockInfo.l_start = 0; + fileLockInfo.l_len = 0; + if (fcntl(fd_, F_SETLK, &fileLockInfo) == -1) { + LOG_ERROR("failed to release file lock error %{public}d.", errno); + errCode = E_ERROR; + } + close(fd_); + fd_ = -1; + } + return errCode; +} + +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/src/preferences_helper.cpp b/preferences/frameworks/native/src/preferences_helper.cpp index b62916ae..498a6065 100644 --- a/preferences/frameworks/native/src/preferences_helper.cpp +++ b/preferences/frameworks/native/src/preferences_helper.cpp @@ -34,12 +34,8 @@ std::map> PreferencesHelper::prefsCach std::mutex PreferencesHelper::prefsCacheMutex_; static bool IsFileExist(const std::string &path) { - FILE *file = std::fopen(path.c_str(), "r"); - if (file != nullptr) { - std::fclose(file); - return true; - } - return false; + struct stat buffer; + return (stat(path.c_str(), &buffer) == 0); } std::string PreferencesHelper::GetRealPath(const std::string &path, int &errorCode) @@ -73,12 +69,6 @@ std::string PreferencesHelper::GetRealPath(const std::string &path, int &errorCo return ""; } #endif - char canonicalPath[PATH_MAX + 1] = { 0 }; - if (REALPATH(filePath.c_str(), canonicalPath, PATH_MAX) == nullptr) { - LOG_ERROR("Failed to obtain real path, errno:%{public}d", errno); - errorCode = E_INVALID_FILE_PATH; - return ""; - } std::string fileName = path.substr(pos + 1, path.length()); if (fileName.empty()) { LOG_ERROR("file name can not be empty."); @@ -86,15 +76,15 @@ std::string PreferencesHelper::GetRealPath(const std::string &path, int &errorCo return ""; } errorCode = E_OK; - std::string realFilePath(canonicalPath); - return realFilePath.append("/").append(fileName); + return path; } -std::shared_ptr PreferencesHelper::GetPreferences(const std::string &path, int &errCode) +std::shared_ptr PreferencesHelper::GetPreferences(const Options &options, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - std::string realPath = GetRealPath(path, errCode); + std::string realPath = GetRealPath(options.filePath, errCode); if (realPath == "" || errCode != E_OK) { + LOG_ERROR("fails to get real path, errCode %{public}d", errCode); return nullptr; } @@ -104,8 +94,8 @@ std::shared_ptr PreferencesHelper::GetPreferences(const std::string return it->second; } - std::string filePath = realPath.c_str(); - std::shared_ptr pref = PreferencesImpl::GetPreferences(filePath); + const_cast(options).filePath = realPath; + std::shared_ptr pref = PreferencesImpl::GetPreferences(options); errCode = pref->Init(); if (errCode != E_OK) { LOG_ERROR("Preferences Init failed."); @@ -131,8 +121,9 @@ int PreferencesHelper::DeletePreferences(const std::string &path) } std::string filePath = realPath.c_str(); - std::string backupPath = PreferencesImpl::MakeBackupPath(filePath); - std::string brokenPath = PreferencesImpl::MakeBrokenPath(filePath); + std::string backupPath = PreferencesImpl::MakeFilePath(filePath, STR_BACKUP); + std::string brokenPath = PreferencesImpl::MakeFilePath(filePath, STR_BROKEN); + std::string lockFilePath = PreferencesImpl::MakeFilePath(filePath, STR_LOCK); std::remove(filePath.c_str()); std::remove(backupPath.c_str()); diff --git a/preferences/frameworks/native/src/preferences_impl.cpp b/preferences/frameworks/native/src/preferences_impl.cpp index 9cb13820..d9811b35 100644 --- a/preferences/frameworks/native/src/preferences_impl.cpp +++ b/preferences/frameworks/native/src/preferences_impl.cpp @@ -23,15 +23,17 @@ #include #include "adaptor.h" +#include "data_preferences_observer_stub.h" #include "log_print.h" #include "preferences_errno.h" #include "preferences_xml_utils.h" #include "securec.h" -#include "task_executor.h" -#include "task_scheduler.h" namespace OHOS { namespace NativePreferences { + +ExecutorPool PreferencesImpl::executorPool_ = ExecutorPool(1, 0); + static bool IsFileExist(const std::string &inputPath) { char path[PATH_MAX + 1] = { 0x00 }; @@ -40,34 +42,21 @@ static bool IsFileExist(const std::string &inputPath) return false; } const char *pathString = path; - FILE *file = std::fopen(pathString, "r"); - if (file != nullptr) { - std::fclose(file); - return true; - } - return false; + struct stat buffer; + return (stat(pathString, &buffer) == 0); } -PreferencesImpl::PreferencesImpl(const std::string &filePath) - : loaded_(false), filePath_(filePath), backupPath_(MakeBackupPath(filePath_)), - brokenPath_(MakeBrokenPath(filePath_)) +PreferencesImpl::PreferencesImpl(const Options &options) : loaded_(false), options_(options) { currentMemoryStateGeneration_ = 0; diskStateGeneration_ = 0; } -std::string PreferencesImpl::MakeBackupPath(const std::string &prefPath) +std::string PreferencesImpl::MakeFilePath(const std::string &prefPath, const std::string &suffix) { - std::string backupPath = prefPath; - backupPath += ".bak"; - return backupPath; -} - -std::string PreferencesImpl::MakeBrokenPath(const std::string &prefPath) -{ - std::string brokenPath = prefPath; - brokenPath += ".bak"; - return brokenPath; + std::string filePath = prefPath; + filePath += suffix; + return filePath; } PreferencesImpl::~PreferencesImpl() @@ -88,8 +77,9 @@ bool PreferencesImpl::StartLoadFromDisk() std::lock_guard lock(mutex_); loaded_ = false; } - TaskScheduler::Task task = std::bind(PreferencesImpl::LoadFromDisk, shared_from_this()); - return TaskExecutor::GetInstance().Execute(std::move(task)); + + ExecutorPool::Task task = std::bind(PreferencesImpl::LoadFromDisk, shared_from_this()); + return (executorPool_.Execute(std::move(task)) == ExecutorPool::INVALID_TASK_ID) ? false : true; } int PreferencesImpl::CheckKey(const std::string &key) @@ -113,23 +103,23 @@ void PreferencesImpl::LoadFromDisk(std::shared_ptr pref) return; } - if (IsFileExist(pref->backupPath_)) { - if (std::remove(pref->filePath_.c_str())) { - LOG_ERROR("Couldn't delete file %{private}s when LoadFromDisk and backup exist.", pref->filePath_.c_str()); + std::string backupPath = MakeFilePath(pref->options_.filePath, STR_BACKUP); + if (IsFileExist(backupPath)) { + if (std::remove(pref->options_.filePath.c_str())) { + LOG_ERROR("Couldn't delete file %{private}s when LoadFromDisk and backup exist.", + pref->options_.filePath.c_str()); } - if (std::rename(pref->backupPath_.c_str(), pref->filePath_.c_str())) { + if (std::rename(backupPath.c_str(), pref->options_.filePath.c_str())) { LOG_ERROR("Couldn't rename backup file %{private}s to file %{private}s,when LoadFromDisk and backup " - "exist.", - pref->backupPath_.c_str(), pref->filePath_.c_str()); + "exist.", backupPath.c_str(), pref->options_.filePath.c_str()); } else { - PreferencesXmlUtils::LimitXmlPermission(pref->filePath_); + PreferencesXmlUtils::LimitXmlPermission(pref->options_.filePath); } } - if (IsFileExist(pref->filePath_)) { - pref->ReadSettingXml(pref->filePath_, pref->map_); + if (IsFileExist(pref->options_.filePath)) { + pref->ReadSettingXml(pref->options_.filePath, pref->map_); } - pref->loaded_ = true; pref->cond_.notify_all(); } @@ -144,43 +134,46 @@ void PreferencesImpl::AwaitLoadFile() void PreferencesImpl::WriteToDiskFile(std::shared_ptr pref, std::shared_ptr mcr) { - if (IsFileExist(pref->filePath_)) { + std::string backupPath = MakeFilePath(pref->options_.filePath, STR_BACKUP); + if (IsFileExist(pref->options_.filePath)) { bool needWrite = pref->CheckRequestValidForStateGeneration(*mcr); if (!needWrite) { mcr->SetDiskWriteResult(false, E_OK); return; } - - if (IsFileExist(pref->backupPath_)) { - if (std::remove(pref->filePath_.c_str())) { + if (IsFileExist(backupPath)) { + if (std::remove(pref->options_.filePath.c_str())) { LOG_ERROR("Couldn't delete file %{private}s when writeToFile and backup exist.", - pref->filePath_.c_str()); + pref->options_.filePath.c_str()); } } else { - if (std::rename(pref->filePath_.c_str(), pref->backupPath_.c_str())) { - LOG_ERROR("Couldn't rename file %{private}s to backup file %{private}s", pref->filePath_.c_str(), - pref->backupPath_.c_str()); + if (std::rename(pref->options_.filePath.c_str(), backupPath.c_str())) { + LOG_ERROR("Couldn't rename file %{private}s to backup file %{private}s", + pref->options_.filePath.c_str(), backupPath.c_str()); mcr->SetDiskWriteResult(false, E_ERROR); return; } else { - PreferencesXmlUtils::LimitXmlPermission(pref->backupPath_); + PreferencesXmlUtils::LimitXmlPermission(backupPath); } } } - - if (pref->WriteSettingXml(pref->filePath_, mcr->writeToDiskMap_)) { - if (IsFileExist(pref->backupPath_) && std::remove(pref->backupPath_.c_str())) { - LOG_ERROR("Couldn't delete backup file %{private}s when writeToFile finish.", pref->backupPath_.c_str()); + if (pref->WriteSettingXml(pref->options_.filePath, mcr->writeToDiskMap_)) { + if (IsFileExist(backupPath) && std::remove(backupPath.c_str())) { + LOG_ERROR("Couldn't delete backup file %{private}s when writeToFile finish.", backupPath.c_str()); } pref->diskStateGeneration_ = mcr->memoryStateGeneration_; mcr->SetDiskWriteResult(true, E_OK); } else { - /* Clean up an unsuccessfully written file */ - if (IsFileExist(pref->filePath_)) { - if (std::remove(pref->filePath_.c_str())) { - LOG_ERROR("Couldn't clean up partially-written file %{private}s", pref->filePath_.c_str()); + // restore backup if write fails + if (IsFileExist(pref->options_.filePath)) { + if (std::remove(pref->options_.filePath.c_str())) { + LOG_ERROR("Couldn't clean up partially-written file %{private}s", pref->options_.filePath.c_str()); } } + if (std::rename(backupPath.c_str(), pref->options_.filePath.c_str())) { + LOG_ERROR("Couldn't rename backup file %{private}s to file %{private}s", backupPath.c_str(), + pref->options_.filePath.c_str()); + } mcr->SetDiskWriteResult(false, E_ERROR); } } @@ -299,7 +292,7 @@ bool PreferencesImpl::ReadSettingXml( { std::vector settings; if (!PreferencesXmlUtils::ReadSettingXml(prefPath, settings)) { - LOG_ERROR("ReadSettingXml:%{private}s failed!", filePath_.c_str()); + LOG_ERROR("ReadSettingXml:%{private}s failed!", options_.filePath.c_str()); return false; } @@ -372,7 +365,7 @@ bool PreferencesImpl::WriteSettingXml( elem.key_ = it->first; PreferencesValue value = it->second; - WriteXmlElement(elem, value, filePath_); + WriteXmlElement(elem, value, options_.filePath); settings.push_back(elem); } @@ -391,24 +384,59 @@ bool PreferencesImpl::HasKey(const std::string &key) return (map_.find(key) != map_.end()); } -void PreferencesImpl::RegisterObserver(std::shared_ptr preferencesObserver) +int PreferencesImpl::RegisterObserver(std::shared_ptr preferencesObserver, RegisterMode mode) { std::lock_guard lock(mutex_); - std::weak_ptr weakPreferencesObserver = preferencesObserver; - preferencesObservers_.push_back(weakPreferencesObserver); + if (mode == RegisterMode::LOCAL_CHANGE) { + std::weak_ptr weakPreferencesObserver = preferencesObserver; + localObservers_.push_back(weakPreferencesObserver); + } else { + auto dataObsMgrClient = DataObsMgrClient::GetInstance(); + if (dataObsMgrClient == nullptr) { + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + sptr observer(new (std::nothrow) DataPreferencesObserverStub(preferencesObserver)); + int errcode = dataObsMgrClient->RegisterObserver(MakeUri(), observer); + if (errcode != 0) { + LOG_ERROR("RegisterObserver multiProcessChange failed, errCode %{public}d", errcode); + return errcode; + } + multiProcessObservers_.push_back(observer); + } + return E_OK; } -void PreferencesImpl::UnRegisterObserver(std::shared_ptr preferencesObserver) +int PreferencesImpl::UnRegisterObserver(std::shared_ptr preferencesObserver, RegisterMode mode) { std::lock_guard lock(mutex_); - for (auto it = preferencesObservers_.begin(); it != preferencesObservers_.end(); ++it) { - std::weak_ptr weakPreferencesObserver = *it; - std::shared_ptr sharedPreferencesObserver = weakPreferencesObserver.lock(); - if (!sharedPreferencesObserver || sharedPreferencesObserver == preferencesObserver) { - preferencesObservers_.erase(it); + if (mode == RegisterMode::LOCAL_CHANGE) { + for (auto it = localObservers_.begin(); it != localObservers_.end(); ++it) { + std::weak_ptr weakPreferencesObserver = *it; + std::shared_ptr sharedObserver = weakPreferencesObserver.lock(); + if (!sharedObserver || sharedObserver == preferencesObserver) { + localObservers_.erase(it); + break; + } + } + return E_OK; + } + for (auto it = multiProcessObservers_.begin(); it != multiProcessObservers_.end(); ++it) { + std::shared_ptr sharedObserver = (*it)->preferencesObserver_.lock(); + if (!sharedObserver || sharedObserver == preferencesObserver) { + auto dataObsMgrClient = DataObsMgrClient::GetInstance(); + if (dataObsMgrClient == nullptr) { + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + int errcode = dataObsMgrClient->UnregisterObserver(MakeUri(), *it); + if (errcode != 0) { + LOG_ERROR("RegisterObserver multiProcessChange failed, errCode %{public}d", errcode); + return errcode; + } + multiProcessObservers_.erase(it); break; } } + return E_OK; } int PreferencesImpl::Put(const std::string &key, const PreferencesValue &value) @@ -451,6 +479,21 @@ int PreferencesImpl::CheckStringValue(const std::string &value) return E_OK; } +Uri PreferencesImpl::MakeUri(const std::string &key) +{ + std::string uriStr; + if (options_.dataGroupId.empty()) { + uriStr = STR_SCHEME + options_.bundleName + STR_SLASH + options_.filePath; + } else { + uriStr = STR_SCHEME + options_.dataGroupId + STR_SLASH + options_.filePath; + } + + if (!key.empty()) { + uriStr = uriStr + STR_QUERY + key; + } + return Uri(uriStr); +} + int PreferencesImpl::Delete(const std::string &key) { int errCode = CheckKey(key); @@ -487,9 +530,9 @@ void PreferencesImpl::Flush() DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::shared_ptr request = commitToMemory(); request->isSyncRequest_ = false; - TaskScheduler::Task task = std::bind(PreferencesImpl::WriteToDiskFile, shared_from_this(), request); - TaskExecutor::GetInstance().Execute(std::move(task)); - + ExecutorPool::Task task = std::bind(PreferencesImpl::WriteToDiskFile, shared_from_this(), request); + executorPool_.Execute(std::move(task)); + notifyPreferencesObserver(*request); } @@ -500,7 +543,8 @@ int PreferencesImpl::FlushSync() std::unique_lock lock(request->reqMutex_); PreferencesImpl::WriteToDiskFile(shared_from_this(), request); if (request->wasWritten_) { - LOG_DEBUG("%{private}s:%{public}" PRId64 " written", filePath_.c_str(), request->memoryStateGeneration_); + LOG_DEBUG("%{private}s:%{public}" PRId64 " written", options_.filePath.c_str(), + request->memoryStateGeneration_); } notifyPreferencesObserver(*request); return request->writeToDiskResult_; @@ -514,30 +558,36 @@ std::shared_ptr PreferencesImpl::commitToM std::vector> preferencesObservers; std::map writeToDiskMap; writeToDiskMap = map_; - if (!modifiedKeys_.empty()) { currentMemoryStateGeneration_++; keysModified = modifiedKeys_; modifiedKeys_.clear(); } memoryStateGeneration = currentMemoryStateGeneration_; - preferencesObservers = preferencesObservers_; + preferencesObservers = localObservers_; return std::make_shared( writeToDiskMap, keysModified, preferencesObservers, memoryStateGeneration); } void PreferencesImpl::notifyPreferencesObserver(const PreferencesImpl::MemoryToDiskRequest &request) { - if ((request.preferencesObservers_.empty()) || (request.keysModified_.empty())) { + if (request.keysModified_.empty()) { return; } + + auto dataObsMgrClient = DataObsMgrClient::GetInstance(); for (auto key = request.keysModified_.begin(); key != request.keysModified_.end(); ++key) { - for (auto it = request.preferencesObservers_.begin(); it != request.preferencesObservers_.end(); ++it) { + for (auto it = request.localObservers_.begin(); it != request.localObservers_.end(); ++it) { std::weak_ptr weakPreferencesObserver = *it; if (std::shared_ptr sharedPreferencesObserver = weakPreferencesObserver.lock()) { sharedPreferencesObserver->OnChange(*key); } } + + if (dataObsMgrClient == nullptr) { + continue; + } + dataObsMgrClient->NotifyChange(MakeUri(*key)); } } @@ -547,7 +597,7 @@ PreferencesImpl::MemoryToDiskRequest::MemoryToDiskRequest( { writeToDiskMap_ = writeToDiskMap; keysModified_ = keysModified; - preferencesObservers_ = preferencesObservers; + localObservers_ = preferencesObservers; memoryStateGeneration_ = memStataGeneration; isSyncRequest_ = false; wasWritten_ = false; diff --git a/preferences/frameworks/native/src/preferences_thread.cpp b/preferences/frameworks/native/src/preferences_thread.cpp new file mode 100644 index 00000000..84374420 --- /dev/null +++ b/preferences/frameworks/native/src/preferences_thread.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "preferences_thread.h" +namespace OHOS { +namespace NativePreferences { +int PthreadSetNameNp(const std::string name) +{ + return pthread_setname_np(pthread_self(), name.c_str()); +} +} // End of namespace NativePreferences +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/interfaces/inner_api/BUILD.gn b/preferences/interfaces/inner_api/BUILD.gn index cffcb5c7..3c13f425 100644 --- a/preferences/interfaces/inner_api/BUILD.gn +++ b/preferences/interfaces/inner_api/BUILD.gn @@ -16,9 +16,14 @@ config("native_preferences_config") { visibility = [ ":*" ] include_dirs = [ "include", - "${preferences_native_path}/include", "${preferences_base_path}/frameworks/common/include", + "${preferences_native_path}/include", ] + if (is_ohos) { + include_dirs += [ "${preferences_native_path}/common/include" ] + } else { + include_dirs += [ "${preferences_native_path}/common/mock/include" ] + } } config("native_preferences_public_config") { @@ -36,13 +41,16 @@ base_sources = [ "${preferences_native_path}/src/preferences_observer.cpp", "${preferences_native_path}/src/preferences_value.cpp", "${preferences_native_path}/src/preferences_xml_utils.cpp", - "${preferences_native_path}/src/task_executor.cpp", ] if (is_ohos) { ohos_shared_library("native_preferences") { all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources + sources += [ + "${preferences_native_path}/common/src/data_preferences_observer_stub.cpp", + "${preferences_native_path}/src/preferences_thread.cpp", + ] innerapi_tags = [ "platformsdk" ] @@ -51,9 +59,12 @@ if (is_ohos) { cflags_cc = [ "-fvisibility=hidden" ] deps = [ "//third_party/libxml2:libxml2" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", - "hilog_native:libhilog", - "hitrace_native:hitrace_meter", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", ] public_configs = [ ":native_preferences_public_config" ] subsystem_name = "distributeddatamgr" @@ -63,7 +74,7 @@ if (is_ohos) { ohos_shared_library("native_preferences") { all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources - + sources += [ "${preferences_native_path}/common/mock/src/data_preferences_observer_stub.cpp" ] innerapi_tags = [ "platformsdk" ] configs = [ ":native_preferences_config" ] @@ -74,9 +85,13 @@ if (is_ohos) { "-stdlib=libc++", ] if (is_mac) { + sources += [ + "${preferences_native_path}/common/mock/src/preferences_thread.cpp", + ] buildos = "mac" defines = [ "MAC_PLATFORM" ] } else { + sources += [ "${preferences_native_path}/src/preferences_thread.cpp" ] buildos = "windows" defines = [ "WINDOWS_PLATFORM" ] ldflags = [ "-lws2_32" ] @@ -94,6 +109,10 @@ if (is_ohos) { ohos_source_set("native_preferences") { all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources + sources += [ + "${preferences_native_path}/common/mock/src/data_preferences_observer_stub.cpp", + "${preferences_native_path}/src/preferences_thread.cpp", + ] defines = [ "ANDROID_PLATFORM" ] @@ -112,7 +131,10 @@ if (is_ohos) { ohos_source_set("native_preferences") { all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources - + sources += [ + "${preferences_native_path}/common/mock/src/data_preferences_observer_stub.cpp", + "${preferences_native_path}/common/mock/src/preferences_thread.cpp", + ] defines = [ "IOS_PLATFORM" ] configs = [ ":native_preferences_config" ] @@ -131,19 +153,22 @@ if (is_ohos) { ohos_static_library("native_preferences_static") { all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources - configs = [ ":native_preferences_config" ] - if (is_mingw || is_mac) { + sources += [ "${preferences_native_path}/common/mock/src/data_preferences_observer_stub.cpp" ] configs += [ ":adaptor_config" ] cflags_cc = [ "-std=c++17", "-stdlib=libc++", ] if (is_mac) { + sources += [ + "${preferences_native_path}/common/mock/src/preferences_thread.cpp", + ] buildos = "mac" defines = [ "MAC_PLATFORM" ] } else { + sources += [ "${preferences_native_path}/src/preferences_thread.cpp" ] buildos = "windows" defines = [ "WINDOWS_PLATFORM" ] ldflags = [ "-lws2_32" ] @@ -153,11 +178,22 @@ ohos_static_library("native_preferences_static") { "//third_party/libxml2:static_libxml2", ] } else { + if (is_ios) { + sources += [ + "${preferences_native_path}/common/mock/src/preferences_thread.cpp", + ] + } else { + sources += [ "${preferences_native_path}/src/preferences_thread.cpp" ] + } + sources += [ "${preferences_native_path}/common/src/data_preferences_observer_stub.cpp" ] deps = [ "//third_party/libxml2:libxml2" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", - "hilog_native:libhilog", - "hitrace_native:hitrace_meter", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", ] } diff --git a/preferences/interfaces/inner_api/include/preferences.h b/preferences/interfaces/inner_api/include/preferences.h index 8a064fb7..ef4b55ed 100644 --- a/preferences/interfaces/inner_api/include/preferences.h +++ b/preferences/interfaces/inner_api/include/preferences.h @@ -27,7 +27,27 @@ namespace OHOS { namespace NativePreferences { +using RegisterMode = PreferencesObserver::RegisterMode; +struct Options { +public: + Options(const std::string inputFilePath) : filePath(inputFilePath) + { + } + + Options(const char *inputFilePath) : filePath(inputFilePath) + { + } + Options(const std::string &inputFilePath, const std::string &inputbundleName, const std::string &inputdataGroupId) + : filePath(inputFilePath), bundleName(inputbundleName), dataGroupId(inputdataGroupId) + { + } + +public: + std::string filePath{ "" }; + std::string bundleName{ "" }; + std::string dataGroupId{ "" }; +}; /** * The function class of the preference. Various operations on preferences instances are provided in this class. */ @@ -280,7 +300,8 @@ public: * * @param preferencesObserver Indicates callback function for data changes. */ - virtual void RegisterObserver(std::shared_ptr preferencesObserver) = 0; + virtual int RegisterObserver( + std::shared_ptr preferencesObserver, RegisterMode mode = RegisterMode::LOCAL_CHANGE) = 0; /** * @brief Unregister an existing observer. @@ -289,7 +310,8 @@ public: * * @param preferencesObserver Indicates callback function for data changes. */ - virtual void UnRegisterObserver(std::shared_ptr preferencesObserver) = 0; + virtual int UnRegisterObserver( + std::shared_ptr preferencesObserver, RegisterMode mode = RegisterMode::LOCAL_CHANGE) = 0; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/interfaces/inner_api/include/preferences_errno.h b/preferences/interfaces/inner_api/include/preferences_errno.h index bea67f6f..c9408fc1 100644 --- a/preferences/interfaces/inner_api/include/preferences_errno.h +++ b/preferences/interfaces/inner_api/include/preferences_errno.h @@ -29,103 +29,113 @@ constexpr int E_OK = 0; /** * @brief The base code of the exception error code. */ -constexpr int E_BASE = -1000; // different from the other errno. +constexpr int E_BASE = 15500000; + +/** +* @brief The error when the capability not supported. +*/ +constexpr int E_NOT_SUPPORTED = 801; /** * @brief The error code for common exceptions. */ -constexpr int E_ERROR = (E_BASE - 1); +constexpr int E_ERROR = E_BASE; /** * @brief The error code for resource has been stopped, killed or destroyed. */ -constexpr int E_STALE = (E_BASE - 2); // Resource has been stopped, killed or destroyed. +constexpr int E_STALE = (E_BASE + 1); // Resource has been stopped, killed or destroyed. /** * @brief The error code for the input args is invalid. */ -constexpr int E_INVALID_ARGS = (E_BASE - 3); // the input args is invalid. +constexpr int E_INVALID_ARGS = (E_BASE + 2); // the input args is invalid. /** * @brief The error code for out of memory. */ -constexpr int E_OUT_OF_MEMORY = (E_BASE - 4); // out of memory +constexpr int E_OUT_OF_MEMORY = (E_BASE + 3); // out of memory /** * @brief The error code for operation is not permitted. */ -constexpr int E_NOT_PERMIT = (E_BASE - 5); // operation is not permitted +constexpr int E_NOT_PERMIT = (E_BASE + 4); // operation is not permitted /** * @brief The error code for the key is empty. */ -constexpr int E_KEY_EMPTY = (E_BASE - 6); +constexpr int E_KEY_EMPTY = (E_BASE + 5); /** * @brief The error code for the key string length exceed the max length (80). */ -constexpr int E_KEY_EXCEED_MAX_LENGTH = (E_BASE - 7); +constexpr int E_KEY_EXCEED_MAX_LENGTH = (E_BASE + 6); /** * @brief The error code for the former Preferences object pointer is held by another thread and may * not be able to be deleted. */ -constexpr int E_PTR_EXIST_ANOTHER_HOLDER = (E_BASE - 8); +constexpr int E_PTR_EXIST_ANOTHER_HOLDER = (E_BASE + 7); /** -* @brief The error code when deleting a file fails. +* @brief The error code for the file path is relative path. */ -constexpr int E_DELETE_FILE_FAIL = (E_BASE - 9); +constexpr int E_RELATIVE_PATH = (E_BASE + 8); /** * @brief The error code for the file path is empty. */ -constexpr int E_EMPTY_FILE_PATH = (E_BASE - 10); +constexpr int E_EMPTY_FILE_PATH = (E_BASE + 9); /** -* @brief The error code for the file path is relative path. +* @brief The error code when deleting a file fails. */ -constexpr int E_RELATIVE_PATH = (E_BASE - 11); +constexpr int E_DELETE_FILE_FAIL = (E_BASE + 10); /** * @brief The error code for the file name is empty. */ -constexpr int E_EMPTY_FILE_NAME = (E_BASE - 12); +constexpr int E_EMPTY_FILE_NAME = (E_BASE + 11); /** * @brief The error code for the file path is invalid. */ -constexpr int E_INVALID_FILE_PATH = (E_BASE - 13); +constexpr int E_INVALID_FILE_PATH = (E_BASE + 12); /** * @brief The error code for the file path exceeds the max length. */ -constexpr int E_PATH_EXCEED_MAX_LENGTH = (E_BASE - 14); +constexpr int E_PATH_EXCEED_MAX_LENGTH = (E_BASE + 13); /** * @brief The error code for the value exceeds the max length (8 * 1024). */ -constexpr int E_VALUE_EXCEED_MAX_LENGTH = (E_BASE - 15); +constexpr int E_VALUE_EXCEED_MAX_LENGTH = (E_BASE + 14); /** * @brief The error code for the key exceeds the length limit (32). */ -constexpr int E_KEY_EXCEED_LENGTH_LIMIT = (E_BASE - 16); +constexpr int E_KEY_EXCEED_LENGTH_LIMIT = (E_BASE + 15); /** * @brief The error code for the value exceeds the length limit (128). */ -constexpr int E_VALUE_EXCEED_LENGTH_LIMIT = (E_BASE - 17); +constexpr int E_VALUE_EXCEED_LENGTH_LIMIT = (E_BASE + 16); /** * @brief The error code for the default exceeds the max length (128). */ -constexpr int E_DEFAULT_EXCEED_LENGTH_LIMIT = (E_BASE - 18); +constexpr int E_DEFAULT_EXCEED_LENGTH_LIMIT = (E_BASE + 17); + +/** +* @brief The error code for permission denied. +*/ +constexpr int PERMISSION_DENIED = (E_BASE + 18); /** -* @brief The error code for napi get error. +* @brief Failed to get DataObsMgrClient. */ -constexpr int E_NAPI_GET_ERROR = (E_BASE - 19); +static constexpr int E_GET_DATAOBSMGRCLIENT_FAIL = (E_BASE + 19); } // namespace NativePreferences } // namespace OHOS diff --git a/preferences/interfaces/inner_api/include/preferences_helper.h b/preferences/interfaces/inner_api/include/preferences_helper.h index e40ee9f4..6e813392 100644 --- a/preferences/interfaces/inner_api/include/preferences_helper.h +++ b/preferences/interfaces/inner_api/include/preferences_helper.h @@ -25,7 +25,6 @@ namespace OHOS { namespace NativePreferences { - /** * The observer class of preferences. This class is used to obtain and delete preferences instances. */ @@ -39,12 +38,12 @@ public: * preferences instance is being used in another thread, it will be cached until it will no longer be used to and * performed {@link RemovePreferencesFromCache}. * - * @param path Indicates the preferences file name + * @param options Indicates the preferences configuration * @param errCode Indicates the error code. Returns 0 for success, others for failure. * * @return Returns a Preferences instance matching the specified preferences file name. */ - PREF_API_EXPORT static std::shared_ptr GetPreferences(const std::string &path, int &errCode); + PREF_API_EXPORT static std::shared_ptr GetPreferences(const Options &options, int &errCode); /** * @brief Deletes a preferences instance matching a specified preferences file name. diff --git a/preferences/interfaces/inner_api/include/preferences_observer.h b/preferences/interfaces/inner_api/include/preferences_observer.h index 1d1dffa8..23f1f106 100644 --- a/preferences/interfaces/inner_api/include/preferences_observer.h +++ b/preferences/interfaces/inner_api/include/preferences_observer.h @@ -22,12 +22,13 @@ namespace OHOS { namespace NativePreferences { - /** * The observer class of preferences. */ + class PREF_API_EXPORT PreferencesObserver { public: + enum RegisterMode { LOCAL_CHANGE = 0, MULTI_PRECESS_CHANGE }; PREF_API_EXPORT virtual ~PreferencesObserver(); /** diff --git a/preferences/test/js/BUILD.gn b/preferences/test/js/BUILD.gn index 8f3d227b..e8758b2f 100644 --- a/preferences/test/js/BUILD.gn +++ b/preferences/test/js/BUILD.gn @@ -24,4 +24,12 @@ group("unittest") { "unittest/system_storage/src:unittest", ] } + +#################################performance######################################### +group("performancetest") { + testonly = true + deps = [] + + deps += [ "performance/preferences/src:performancetest" ] +} ############################################################################### diff --git a/preferences/test/js/performance/preferences/src/BUILD.gn b/preferences/test/js/performance/preferences/src/BUILD.gn new file mode 100644 index 00000000..2261498c --- /dev/null +++ b/preferences/test/js/performance/preferences/src/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") + +module_output_path = "preferences/jsPerformance" + +ohos_js_unittest("PreferencesJsPerformanceTest") { + module_out_path = module_output_path + + hap_profile = "./config.json" + + certificate_profile = "./openharmony_sx.p7b" +} + +group("performancetest") { + testonly = true + deps = [ ":PreferencesJsPerformanceTest" ] +} diff --git a/preferences/test/js/performance/preferences/src/PreferencesInstanceCallBackJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesInstanceCallBackJsPref.test.js new file mode 100644 index 00000000..f1ae17f2 --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesInstanceCallBackJsPref.test.js @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const DELETE_BASE_COUNT = 1500; +const BASELINE = 25000; +const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; +const KEY_TEST_BOOLEAN_ELEMENT = 'key_test_boolean'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; + +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesInstanceCallBackJsPref]' + +describe("PreferencesInstanceCallBackJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + await presetFiles(); + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + for (let index = 0; index < BASE_COUNT; index++) { + dataPreferences.removePreferencesFromCacheSync(context, `${NAME}${index}`); + await dataPreferences.deletePreferences(context, `${NAME}${index}`); + } + }) + + async function presetFiles() { // preset 100 files for get or delete + for (let index = 0; index < BASE_COUNT; index++) { + const pref = await dataPreferences.getPreferences(context, `${NAME}${index}`); + pref.putSync(KEY_TEST_FLOAT_ELEMENT, 123456789.00001); + pref.putSync(KEY_TEST_BOOLEAN_ELEMENT, true); + pref.putSync(KEY_TEST_STRING_ELEMENT + '1', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '2', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '3', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '4', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '5', "01234567890123456789012345678901234567890123456789"); + await pref.flush(); + dataPreferences.removePreferencesFromCacheSync(context, `${NAME}${index}`); + } + } + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_GetPreferences without open exist file and repeat one pref + */ + it("GetPreferences_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceGetPreferenceCallbackPerfTest(0); + + function preferenceGetPreferenceCallbackPerfTest(index) { + dataPreferences.getPreferences(context, NAME, function () { + if (index < BASE_COUNT) { + preferenceGetPreferenceCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}GetPreferences_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_GetPreferences with open exist diff file + */ + it("GetPreferences_0002", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceGetPreferenceCallbackPerfTest(0); + + function preferenceGetPreferenceCallbackPerfTest(index) { + dataPreferences.getPreferences(context, `${NAME}${index}`, function () { + if (index < BASE_COUNT) { + preferenceGetPreferenceCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}GetPreferences_0002 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_Flush without repeat one pref + */ + it("Flush_0001", 0, async function (done) { + let pref = await dataPreferences.getPreferences(context, NAME); + let startTime = new Date().getTime(); // time unit is mm + preferenceFlushCallbackPerfTest(0); + + function preferenceFlushCallbackPerfTest(index) { + pref.flush(function () { + if (index < BASE_COUNT) { + preferenceFlushCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}Flush_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_Flush without repeat one pref + */ + it("Flush_0001", 0, async function (done) { + let pref = await dataPreferences.getPreferences(context, NAME); + let startTime = new Date().getTime(); // time unit is mm + preferenceFlushCallbackPerfTest(0); + + function preferenceFlushCallbackPerfTest(index) { + pref.flush(function () { + if (index < BASE_COUNT) { + preferenceFlushCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}Flush_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_removePreferencesFromCache with repeating one pref + */ + it("removePreferencesFromCache_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceRemovePreferencesFromCacheCallbackPerfTest(0); + + function preferenceRemovePreferencesFromCacheCallbackPerfTest(index) { + dataPreferences.removePreferencesFromCache(context, NAME, function () { + if (index < BASE_COUNT) { + preferenceRemovePreferencesFromCacheCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCache_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_removePreferencesFromCache with diff pref + */ + it("removePreferencesFromCache_0002", 0, async function (done) { + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.getPreferences(context, `${NAME}${index}`); // put prefs into cache + } + + let startTime = new Date().getTime(); // time unit is mm + preferenceRemovePreferencesFromCacheCallbackPerfTest(0); + + function preferenceRemovePreferencesFromCacheCallbackPerfTest(index) { + dataPreferences.removePreferencesFromCache(context, `${NAME}${index}`, function () { + if (index < BASE_COUNT) { + preferenceRemovePreferencesFromCacheCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCache_0002 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_DeletePreferences without exist file and repeat one pref + */ + it("DeletePreferences_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceDeletePreferenceCallbackPerfTest(0); + + function preferenceDeletePreferenceCallbackPerfTest(index) { + dataPreferences.deletePreferences(context, NAME, function () { + if (index < BASE_COUNT) { + preferenceDeletePreferenceCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}DeletePreferences_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_DeletePreferences with open exist diff file. + * Warn: this depends on testcase execute order, otherwise testcase will execute very slow. + */ + it("DeletePreferences_0002", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceDeletePreferenceCallbackPerfTest(0); + + function preferenceDeletePreferenceCallbackPerfTest(index) { + dataPreferences.deletePreferences(context, `${NAME}${index}`, function () { + if (index < DELETE_BASE_COUNT) { + preferenceDeletePreferenceCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / DELETE_BASE_COUNT; + console.info(`${TAG}DeletePreferences_0002 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/PreferencesInstancePromiseJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesInstancePromiseJsPref.test.js new file mode 100644 index 00000000..fb59b9ea --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesInstancePromiseJsPref.test.js @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const DELETE_BASE_COUNT = 1500; +const BASELINE = 25000; +const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; +const KEY_TEST_BOOLEAN_ELEMENT = 'key_test_boolean'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; + +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesInstancePromiseJsPref]' + +describe("PreferencesInstancePromiseJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + await presetFiles(); + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + for (let index = 0; index < BASE_COUNT; index++) { + dataPreferences.removePreferencesFromCacheSync(context, `${NAME}${index}`); + await dataPreferences.deletePreferences(context, `${NAME}${index}`); + } + }) + + async function presetFiles() { // preset 100 files for get or delete + for (let index = 0; index < BASE_COUNT; index++) { + const pref = await dataPreferences.getPreferences(context, `${NAME}${index}`); + pref.putSync(KEY_TEST_FLOAT_ELEMENT, 123456789.00001); + pref.putSync(KEY_TEST_BOOLEAN_ELEMENT, true); + pref.putSync(KEY_TEST_STRING_ELEMENT + '1', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '2', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '3', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '4', "01234567890123456789012345678901234567890123456789"); + pref.putSync(KEY_TEST_STRING_ELEMENT + '5', "01234567890123456789012345678901234567890123456789"); + await pref.flush(); + dataPreferences.removePreferencesFromCacheSync(context, `${NAME}${index}`); + } + } + + /** + * @tc.desc PreferencesInstancePromiseJsPref_GetPreferences without open exist file and repeat one pref + */ + it("GetPreferences_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.getPreferences(context, NAME); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}GetPreferences_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_GetPreferences with open exist diff file + */ + it("GetPreferences_0002", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.getPreferences(context, `${NAME}${index}`); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}GetPreferences_0002 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_Flush without repeat one pref + */ + it("Flush_0001", 0, async function () { + let pref = await dataPreferences.getPreferences(context, NAME); + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await pref.flush(); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}Flush_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_removePreferencesFromCache with repeating one pref + */ + it("removePreferencesFromCache_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.removePreferencesFromCache(context, NAME); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCache_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_removePreferencesFromCache with diff pref + */ + it("removePreferencesFromCache_0002", 0, async function () { + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.getPreferences(context, `${NAME}${index}`); // put prefs into cache + } + + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.removePreferencesFromCache(context, `${NAME}${index}`); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCache_0002 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_DeletePreferences without exist file and repeat one pref + */ + it("DeletePreferences_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.deletePreferences(context, NAME); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}DeletePreferences_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstancePromiseJsPref_DeletePreferences with open exist diff file. + * Warn: this depends on testcase execute order, otherwise testcase will execute very slow. + */ + it("DeletePreferences_0002", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < DELETE_BASE_COUNT; index++) { + await dataPreferences.deletePreferences(context, `${NAME}${index}`); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / DELETE_BASE_COUNT; + console.info(`${TAG}DeletePreferences_0002 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/PreferencesInstanceSyncJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesInstanceSyncJsPref.test.js new file mode 100644 index 00000000..023e9f30 --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesInstanceSyncJsPref.test.js @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const BASELINE = 25000; + +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesInstanceSyncJsPref]' + +describe("PreferencesInstanceSyncJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + }) + + /** + * @tc.desc PreferencesInstanceSyncJsPref_RemovePreferencesFromCacheSync with repeating one pref + */ + it("removePreferencesFromCacheSync_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + dataPreferences.removePreferencesFromCacheSync(context, NAME); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCacheSync_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesInstanceSyncJsPref_RemovePreferencesFromCacheSync with diff pref + */ + it("removePreferencesFromCacheSync_0002", 0, async function () { + for (let index = 0; index < BASE_COUNT; index++) { + dataPreferences.getPreferences(context, `${NAME}${index}`); // put prefs into cache + } + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await dataPreferences.removePreferencesFromCacheSync(context, `${NAME}${index}`); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}removePreferencesFromCacheSync_0002 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/PreferencesOperationCallBackJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesOperationCallBackJsPref.test.js new file mode 100644 index 00000000..dc851c15 --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesOperationCallBackJsPref.test.js @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const BASELINE = 25000; +const KEY_TEST_STRING_KEY = 'key_test_string'; +const KEY_TEST_STRING_VAL = '0123456789'; + +var mPreference; +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesOperationCallbackJsPref]' + +describe("PreferencesOperationCallbackJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + mPreference = await dataPreferences.getPreferences(context, NAME); + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + await dataPreferences.deletePreferences(context, NAME); + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_Put + */ + it("put_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferencePutCallbackPerfTest(0); + + function preferencePutCallbackPerfTest(index) { + mPreference.put(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL, function () { + if (index < BASE_COUNT) { + preferencePutCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}put_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_Get + */ + it("get_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceGetCallbackPerfTest(0); + + function preferenceGetCallbackPerfTest(index) { + mPreference.get(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL, function () { + if (index < BASE_COUNT) { + preferenceGetCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}get_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_Has + */ + it("has_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceHasCallbackPerfTest(0); + + function preferenceHasCallbackPerfTest(index) { + mPreference.has(KEY_TEST_STRING_KEY, function () { + if (index < BASE_COUNT) { + preferenceHasCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}has_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) + + /** + * @tc.desc PreferencesInstanceCallBackJsPref_GetAll + */ + it("getAll_0001", 0, async function (done) { + let startTime = new Date().getTime(); // time unit is mm + preferenceGetAllCallbackPerfTest(0); + + function preferenceGetAllCallbackPerfTest(index) { + mPreference.getAll(function () { + if (index < BASE_COUNT) { + preferenceGetAllCallbackPerfTest(index + 1); + } else { + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}getAll_0001 averageTime: ${averageTime} us`); + done(); + expect(averageTime < BASELINE).assertTrue(); + } + }); + }; + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/PreferencesOperationPromiseJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesOperationPromiseJsPref.test.js new file mode 100644 index 00000000..0d1742d7 --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesOperationPromiseJsPref.test.js @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const BASELINE = 25000; +const KEY_TEST_STRING_KEY = 'key_test_string'; +const KEY_TEST_STRING_VAL = '0123456789'; + +var mPreference; +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesOperationPromiseJsPref]' + +describe("PreferencesOperationPromiseJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + mPreference = await dataPreferences.getPreferences(context, NAME); + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + await dataPreferences.deletePreferences(context, NAME); + }) + + /** + * @tc.desc PreferencesOperationPromiseJsPref_Put + */ + it("put_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await mPreference.put(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}put_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesOperationPromiseJsPref_Get + */ + it("get_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await mPreference.get(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}get_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesOperationPromiseJsPref_Has + */ + it("has_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await mPreference.has(KEY_TEST_STRING_KEY); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}has_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesOperationPromiseJsPref_GetAll + */ + it("getAll_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + await mPreference.getAll(); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}getAll_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/PreferencesOperationSyncJsPref.test.js b/preferences/test/js/performance/preferences/src/PreferencesOperationSyncJsPref.test.js new file mode 100644 index 00000000..952768bb --- /dev/null +++ b/preferences/test/js/performance/preferences/src/PreferencesOperationSyncJsPref.test.js @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {beforeAll, beforeEach, describe, afterEach, afterAll, expect, it} from 'deccjsunit/index'; +import dataPreferences from '@ohos.data.preferences' +import featureAbility from '@ohos.ability.featureAbility'; + +const NAME = 'test_preferences'; +const BASE_COUNT = 2000; +const BASELINE = 25000; +const KEY_TEST_STRING_KEY = 'key_test_string'; +const KEY_TEST_STRING_VAL = '0123456789'; + +var mPreference; +var context; + +const TAG = '[SUB_DDM_PERF_PreferencesOperationSyncJsPref]' + +describe("PreferencesOperationSyncJsPref", async function () { + beforeAll(async function () { + console.info(`${TAG}beforeAll`) + context = featureAbility.getContext() + mPreference = await dataPreferences.getPreferences(context, NAME); + }) + + beforeEach(async function () { + console.info(`${TAG}beforeEach`); + }) + + afterEach(async function () { + console.info(`${TAG}afterEach`); + }) + + afterAll(async function () { + console.info(`${TAG}afterAll`) + await dataPreferences.deletePreferences(context, NAME); + }) + + /** + * @tc.desc PreferencesOperationSyncJsPref_PutSync + */ + it("putSync_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + mPreference.putSync(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}putSync_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesOperationSyncJsPref_GetSync + */ + it("getSync_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + mPreference.getSync(KEY_TEST_STRING_KEY, KEY_TEST_STRING_VAL); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}getSync_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) + + /** + * @tc.desc PreferencesOperationSyncJsPref_HasSync + */ + it("hasSync_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + mPreference.hasSync(KEY_TEST_STRING_KEY); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}hasSync_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + + }) + + /** + * @tc.desc PreferencesOperationSyncJsPref_GetAllSync + */ + it("getAllSync_0001", 0, async function () { + let startTime = new Date().getTime(); // time unit is mm + for (let index = 0; index < BASE_COUNT; index++) { + mPreference.getAllSync(); + } + let endTime = new Date().getTime(); + let averageTime = ((endTime - startTime) * 1000) / BASE_COUNT; + console.info(`${TAG}getAllSync_0001 averageTime: ${averageTime} us`); + expect(averageTime < BASELINE).assertTrue(); + }) +}) \ No newline at end of file diff --git a/preferences/test/js/performance/preferences/src/config.json b/preferences/test/js/performance/preferences/src/config.json new file mode 100644 index 00000000..865615d2 --- /dev/null +++ b/preferences/test/js/performance/preferences/src/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "com.example.myapplication", + "vendor": "example", + "version": { + "code": 1, + "name": "1.0" + }, + "apiVersion": { + "compatible": 4, + "target": 5 + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.myapplication", + "name": ".MyApplication", + "deviceType": [ + "tablet", + "2in1", + "default", + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry" + }, + "abilities": [ + { + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "name": "com.example.myapplication.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "MyApplication", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} diff --git a/preferences/test/js/performance/preferences/src/openharmony_sx.p7b b/preferences/test/js/performance/preferences/src/openharmony_sx.p7b new file mode 100644 index 0000000000000000000000000000000000000000..9be1e98fa4c0c28ca997ed660112fa16b194f0f5 GIT binary patch literal 3437 zcmcgvX>b$g8MY4FF(5FQyMT=#m||qU)nQ9cId-MBB-<-lvSdq&snM}IENNF>t+bK| zgowuF2vC|SxSZxNN5eHhV%(WPpbeB9Fc3;JDMtzMBv1-XAc2N~c2_tCXW&OCGw6qQ z-s9VS-tT?h=bI0tMS+~WDXqHJyCPmLzdbE-fV8Nd&*MRZfG8(#POFZG3xs@Lb{0ry z=R8j3wWo!5g=yjKx#BoZMFS)uA)H}cTp@-^K`9VV?RC3J59@}eik*>n|pRKOLZ zxdn7G!Yv@9O#y<&eUy{)vMXb;fQR)ffVAADQsEMXm;IBMDLfLD0w^U;6%HVo-0Q_5 zCHEa?DBuauNpZzoF+tK27w#n~?u%toS-DhR4k@Q*{7x^8Q=D6&kd^_~J#VVG2LXkL zaAy=}U*?Jto)9hx5MGjdp9hcQAu@tfk_;l!PeyxPY<8b&+&D!CyaBh9=8BSVKLpk4 z4Ml3yY|&Th)vyK4cpC{!uU8v2YBlVV`d~(nz&<@{G1oe*DHub1z7~J5*;s2bX<)_* zV_GbsPQg`(&rpxRb_*Od7}++3+liSw-$!1 zs5*g}EHWhI3i|!-FcfzYL0`SL-rq>LENC;PMl)G(0(1U2%Va|smp0UFx0xd@soZA* zD5LYc4OlbE7@ARt#h}rr3>K@bf%B#^-c+xz8Hr)0D5ExIFltezN@Hn8>o5d~bSfYtkc+_Z&kI#-N5_GhCg*V-^TSO=!G~ z(fXy{n2XV+k}6w_W`dTOP2a4u0ly;ANZ>4OxSKAzFB!yBzdo`gX zO?o|H@WiAw$y6l?=^3jA_Hy0S)nTYs12;4hKE&ekQ|>?|ZLJ}#F`2BczC7kdE4@xV zZBD_)Otwjhz+NSaz?d45!;FsGSu-#qh#hStD%B}f!mCT!KqzSo>I`NGH_9Dea$1Qi zg29Ydt!~lQVR99_T7#Hije~(12drl-P)SV?QR*9sus`8th-8^OQ7@xI$(Yp|^;bL1 zR50O$mDXw6P>i7B(TJ)ciPzTE>XY%X6HAa)b#OBRXv&~%Bw|J#Y><i4=e%95bjtw|cJp=#P#Pf#*luqI_wR;fISDCJhAqSG6R%xItn%~QtZ@m%&u zjGGLX;t6Ls62eQvNmf@v+}J%54^CygxRZ`?8X#r|wkev7(s;Ou4T#y1XNNf)h;o7z z8a^Lfq<1uH`E{G9E z*(=)Css_LSk=>E9jr)s5^2-!+MN=Ds}>1hRma4`uCIz9%p3O77839E{xf z4c_I?**|1`K2tg4!Hvyrou4BsJQuv*UfF)<%CelYIS>D^o?X)3+MK%la6kooW8&G@BU)Y0hT`+mOm$Z_%rB=a%o>I z!2c6lHyKQN)VjiFwa!eE^p8jc$sy$vB+8i25lI~6KPFFh$!o$avA~rj#L6xvR|Z83 z*WD6T9e+5Pyy=F+)pNTf{ny3cy>7Rkd3o*TS?TZJ`NS^NF2%HMkyS{?uJ$`!P4_L^ z1`NFDUbNyg_qREifgktnp1_v{Jbb`7m}2PTyUdOmtJj~m z9bB=ecw4_^rw1IW=of+>nrW5=d3k`3qHCxsIN_F{T1A545};;+fsyC&qChi+YV zr~M63H8ZLCPYmsjY>ls9cL%I)F|JIW-#+48$+lD4k*(P*kDM%zx_fvu4u5ZYUnI}5 zdrycFq>xFU)&X3p@pP2u%$o}}YcRn(MhJ&B2o?KS@cIVz>Ye%o^xV?CB{_Qhu z;}_q1bvO^g{8<3!gYbo4Di{8qzV+(9 zdlmksohQmRTs@qB;(Wo?dER_ux6XQb@q$tQPW?CMu6GVQd;R=iR;-S{Kr%Zks7>b1 zNs{|-+jhObYE}NR&`TGGr^h^4bjh%c>R#@=8nM&Md>_a+zVulsl;){flFekV1t9ob z+SqfV_Pv3$2f)bQ8%Ul2>fdYR^1zs0BQF~olsOj5AodC&Q_7SMFzsz2 z9newxE&jodk~tNHwl%LBMMDbrk=(^b literal 0 HcmV?d00001 diff --git a/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js index 620c9420..afce5544 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesHelperJsunit.test.js @@ -34,9 +34,9 @@ describe('PreferencesHelperJsunit', function () { }) /** - * @tc.name getPreferencesSync interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0010 - * @tc.desc getPreferencesSync interface test + * @tc.name getPreferences interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_001 + * @tc.desc getPreferences interface test */ it('testGetPreferencesHelper001', 0, async function () { mPreferences = await data_preferences.getPreferences(context, NAME); @@ -48,7 +48,7 @@ describe('PreferencesHelperJsunit', function () { /** * @tc.name getPreferences interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0020 + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_002 * @tc.desc getPreferences interface test */ it('testGetPreferencesHelper002', 0, async function (done) { @@ -65,9 +65,115 @@ describe('PreferencesHelperJsunit', function () { await promise; }) + /** + * @tc.name getPreferences interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_003 + * @tc.desc getPreferences interface test + */ + it('testGetPreferencesHelper003', 0, async function (done) { + try { + mPreferences = await data_preferences.getPreferences(context, { name: NAME }); + done(); + expect(mPreferences != null).assertTrue(); + } catch(err) { + expect(err).assertFail(); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_004 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper004', 0, async function (done) { + try { + await data_preferences.getPreferences(context, { name: NAME, dataGroupId: "123456" }); + } catch(err) { + done(); + expect('15501001').assertEqual(err.code); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_005 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper005', 0, async function (done) { + try { + await data_preferences.getPreferences(undefined, { name: NAME }); + } catch(err) { + done(); + expect('401').assertEqual(err.code); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_006 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper006', 0, async function (done) { + try { + await data_preferences.getPreferences(null, { name: NAME }); + } catch(err) { + done(); + expect('401').assertEqual(err.code); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_007 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper007', 0, async function (done) { + try { + await data_preferences.getPreferences({}, { name: NAME }); + } catch(err) { + done(); + expect('401').assertEqual(err.code); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_008 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper008', 0, async function (done) { + try { + let myContext = { + stageMode: true, + } + await data_preferences.getPreferences(myContext, { name: NAME }); + } catch(err) { + done(); + expect('15500000').assertEqual(err.code); + } + }) + + /** + * @tc.name getPreferencesSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_getPreferences_009 + * @tc.desc getPreferencesSync interface test + */ + it('testGetPreferencesHelper009', 0, async function (done) { + try { + let myContext = { + stageMode: false, + } + mPreferences = await data_preferences.getPreferences(myContext, { name: NAME }); + done(); + expect(mPreferences != null).assertTrue(); + } catch(err) { + expect(err).assertFail(); + } + }) + /** * @tc.name removePreferencesFromCache interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0030 + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_removePreferencesFromCache_001 * @tc.desc removePreferencesFromCache interface test */ it('testRemovePreferencesFromCache001', 0, async function (done) { @@ -82,12 +188,42 @@ describe('PreferencesHelperJsunit', function () { done(); }) + /** + * @tc.name removePreferencesFromCache interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_removePreferencesFromCache_002 + * @tc.desc removePreferencesFromCache interface test + */ + it('testRemovePreferencesFromCache002', 0, async function (done) { + let perf = await data_preferences.getPreferences(context, { name: NAME }); + perf = null; + try { + await data_preferences.removePreferencesFromCache(context, { name: NAME }); + done(); + } catch(err) { + expect(err).assertFail(); + } + }) + + /** + * @tc.name removePreferencesFromCache interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_removePreferencesFromCache_003 + * @tc.desc removePreferencesFromCache interface test + */ + it('testRemovePreferencesFromCache003', 0, async function (done) { + try { + await data_preferences.removePreferencesFromCache(context, { name: NAME, dataGroupId: "123456" }); + } catch(err) { + done(); + expect('15501001').assertEqual(err.code); + } + }) + /** * @tc.name deletePreferences interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0060 + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_deletePreferences_001 * @tc.desc deletePreferences interface test */ - it('testDeletePreferencesHelper002', 0, async function (done) { + it('testDeletePreferencesHelper001', 0, async function (done) { let perf = await data_preferences.getPreferences(context, NAME); perf = null; const promise = data_preferences.deletePreferences(context, NAME); @@ -100,26 +236,40 @@ describe('PreferencesHelperJsunit', function () { }) /** - * @tc.name put interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_0140 - * @tc.desc put interface test + * @tc.name deletePreferences interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_deletePreferences_002 + * @tc.desc deletePreferences interface test */ - it('testPreferencesRegisterObserver001', 0, async function () { - await mPreferences.clear(); - var observer = function (key) { - console.info('testPreferencesRegisterObserver001 key' + key); - expect('abcd').assertEqual(key); - }; - await mPreferences.on('change', observer); - await mPreferences.put(KEY_TEST_STRING_ELEMENT, "abcd"); + it('testDeletePreferencesHelper002', 0, async function (done) { + let perf = await data_preferences.getPreferences(context, { name: NAME }); + try { + await data_preferences.deletePreferences(context, { name: NAME }); + done(); + } catch(err) { + expect(err).assertFail(); + } + }) + + /** + * @tc.name deletePreferences interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_deletePreferences_003 + * @tc.desc removePreferencesFromCache interface test + */ + it('testDeletePreferencesHelper003', 0, async function (done) { + try { + await data_preferences.deletePreferences(context, { name: NAME, dataGroupId: "123456" }); + } catch(err) { + done(); + expect('15501001').assertEqual(err.code); + } }) /** * @tc.name repeat on interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_0150 + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_on_001 * @tc.desc repeat on interface test */ - it('testPreferencesRegisterObserver002', 0, async function () { + it('testPreferencesOn001', 0, async function () { await mPreferences.clear(); var observer = function (key) { console.info('testPreferencesRegisterObserver002 key' + key); @@ -132,10 +282,10 @@ describe('PreferencesHelperJsunit', function () { /** * @tc.name off interface test - * @tc.number SUB_DDM_AppDataFWK_JSPreferences_0160 + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_off_001 * @tc.desc off interface test */ - it('testPreferencesUnRegisterObserver001', 0, async function () { + it('testPreferencesOff001', 0, async function () { var observer = function (key) { console.info('testPreferencesUnRegisterObserver001 key' + key); expect('').assertEqual(key); diff --git a/preferences/test/js/unittest/preferences/src/config.json b/preferences/test/js/unittest/preferences/src/config.json index e1b1bc28..865615d2 100644 --- a/preferences/test/js/unittest/preferences/src/config.json +++ b/preferences/test/js/unittest/preferences/src/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/preferences/test/js/unittest/storage/src/config.json b/preferences/test/js/unittest/storage/src/config.json index e1b1bc28..865615d2 100644 --- a/preferences/test/js/unittest/storage/src/config.json +++ b/preferences/test/js/unittest/storage/src/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/preferences/test/js/unittest/system_storage/src/config.json b/preferences/test/js/unittest/system_storage/src/config.json index e1b1bc28..865615d2 100644 --- a/preferences/test/js/unittest/system_storage/src/config.json +++ b/preferences/test/js/unittest/system_storage/src/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/preferences/test/native/BUILD.gn b/preferences/test/native/BUILD.gn index 23ea3141..fcfd8999 100644 --- a/preferences/test/native/BUILD.gn +++ b/preferences/test/native/BUILD.gn @@ -38,7 +38,11 @@ ohos_unittest("NativePreferencesTest") { configs = [ ":module_private_config" ] - external_deps = [ "hilog_native:libhilog" ] + external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", + "hilog:libhilog", + ] deps = [ "${preferences_innerapi_path}:native_preferences_static", diff --git a/preferences/test/native/fuzztest/preferences_fuzzer/BUILD.gn b/preferences/test/native/fuzztest/preferences_fuzzer/BUILD.gn index a24c0786..3388a4b2 100644 --- a/preferences/test/native/fuzztest/preferences_fuzzer/BUILD.gn +++ b/preferences/test/native/fuzztest/preferences_fuzzer/BUILD.gn @@ -36,8 +36,10 @@ ohos_fuzztest("PreferencesFuzzTest") { deps = [ "${preferences_innerapi_path}:native_preferences_static" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", - "hilog_native:libhilog", + "hilog:libhilog", ] } diff --git a/preferences/test/native/unittest/preferences_file_test.cpp b/preferences/test/native/unittest/preferences_file_test.cpp index a4593e27..8addb083 100644 --- a/preferences/test/native/unittest/preferences_file_test.cpp +++ b/preferences/test/native/unittest/preferences_file_test.cpp @@ -126,41 +126,12 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_002, TestSize.Level1) /** * @tc.name: NativePreferencesFileTest_003 - * @tc.desc: test two same file path - * @tc.type: FUNC - * @tc.require: AR000CU2BN - * @tc.author: liulinna - */ -HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_003, TestSize.Level1) -{ - std::string absolutePath = "/data/test1"; - std::string relativePath = "/data/test/../test1"; - std::remove(absolutePath.c_str()); - - int errCode = E_OK; - std::shared_ptr pref1 = PreferencesHelper::GetPreferences(absolutePath, errCode); - EXPECT_EQ(errCode, E_OK); - - errCode = E_OK; - std::shared_ptr pref2 = PreferencesHelper::GetPreferences(relativePath, errCode); - EXPECT_EQ(errCode, E_OK); - - EXPECT_EQ(pref1, pref2); - - pref1 = nullptr; - pref2 = nullptr; - int result = PreferencesHelper::DeletePreferences(absolutePath); - EXPECT_EQ(result, E_OK); -} - -/** - * @tc.name: NativePreferencesFileTest_004 * @tc.desc: test FlushSync one times and five times * @tc.type: FUNC * @tc.require: AR000CU2BN * @tc.author: liulinna */ -HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_004, TestSize.Level1) +HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_003, TestSize.Level1) { std::string file = "/data/test/test"; int ret = PreferencesHelper::DeletePreferences(file); @@ -229,13 +200,13 @@ HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_004, TestSize.Level1) } /** - * @tc.name: NativePreferencesFileTest_005 + * @tc.name: NativePreferencesFileTest_004 * @tc.desc: test Flush one times and five times * @tc.type: FUNC * @tc.require: AR000CU2BN * @tc.author: liulinna */ -HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_005, TestSize.Level3) +HWTEST_F(PreferencesFileTest, NativePreferencesFileTest_004, TestSize.Level3) { std::string file = "/data/test/test"; int ret = PreferencesHelper::DeletePreferences(file); diff --git a/relational_store/CMakeLists.txt b/relational_store/CMakeLists.txt index 964f741a..71f9d3d1 100644 --- a/relational_store/CMakeLists.txt +++ b/relational_store/CMakeLists.txt @@ -16,6 +16,8 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/common/src r aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/relationalstore/src relational_store_src) #aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/rdb/src relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/src relational_store_src) +list(REMOVE_ITEM relational_store_src "${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/src/general_endian.cpp") +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dataability/src relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dataability/src relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb/src relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb_bms_adaptor/src relational_store_src) @@ -44,6 +46,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../data_share/interfaces/inner_a include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/base/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/safwk/native/include) include_directories(${MOCK_DIR}/sqlite/include) +include_directories(${MOCK_DIR}/filemanagement/file_api/interfaces/kits) include(${MOCK_DIR}/include/CMakeLists.txt OPTIONAL) include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) diff --git a/relational_store/CODEOWNERS b/relational_store/CODEOWNERS new file mode 100644 index 00000000..7cfaea60 --- /dev/null +++ b/relational_store/CODEOWNERS @@ -0,0 +1,17 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# any change to +# interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h +# needs to be reviewed by @leonchan5 +interfaces/inner_api/rdb/include/distributeddata_relational_store_ipc_interface_code.h @leonchan5 \ No newline at end of file diff --git a/relational_store/bundle.json b/relational_store/bundle.json index cb43a48b..0eb7194b 100644 --- a/relational_store/bundle.json +++ b/relational_store/bundle.json @@ -48,6 +48,7 @@ "ram": "350", "deps": { "components": [ + "ability_base", "ability_runtime", "bundle_framework", "common_event_service", @@ -62,12 +63,8 @@ "samgr" ], "third_party": [ - "gtest_main", + "googletest", "icu", - "libsec_shared", - "libxml2", - "shared_icui18n", - "shared_icuuc", "sqlite" ] }, @@ -79,7 +76,7 @@ "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb:native_rdb", "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb_bms_adapter:rdb_bms_adapter", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/cloud_data:clouddata", - "//foundation/distributeddatamgr/relational_store/interfaces/ndk:native_rdb_ndk", + "//foundation/distributeddatamgr/relational_store/interfaces/ndk/src:native_rdb_ndk", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/dataability:dataability", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/rdb:rdb", "//foundation/distributeddatamgr/relational_store/frameworks/js/napi/rdb:napi_rdb", @@ -87,7 +84,7 @@ ], "inner_kits": [ { - "name": "//foundation/distributeddatamgr/relational_store/interfaces/ndk:native_rdb_ndk", + "name": "//foundation/distributeddatamgr/relational_store/interfaces/ndk/src:native_rdb_ndk", "header": { "header_files": [ "oh_predicates.h", diff --git a/relational_store/frameworks/js/napi/cloud_data/include/js_config.h b/relational_store/frameworks/js/napi/cloud_data/include/js_config.h index 6bf77d68..b49b9c01 100644 --- a/relational_store/frameworks/js/napi/cloud_data/include/js_config.h +++ b/relational_store/frameworks/js/napi/cloud_data/include/js_config.h @@ -28,7 +28,7 @@ public: static napi_value New(napi_env env, napi_callback_info info); enum { - /* exported js Action is (CloudData::Action-1) */ + /* exported js ClearAction is (CloudData::ClearAction-1) */ CLEAR_CLOUD_INFO = 0, CLEAR_CLOUD_DATA_AND_INFO = 1, }; diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp index 0f6aa030..869ab801 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp @@ -324,6 +324,7 @@ napi_value JsConfig::InitConfig(napi_env env, napi_value exports) DECLARE_NAPI_STATIC_FUNCTION("enableCloud", JsConfig::EnableCloud), DECLARE_NAPI_STATIC_FUNCTION("disableCloud", JsConfig::DisableCloud), DECLARE_NAPI_STATIC_FUNCTION("changeAppCloudSwitch", JsConfig::ChangeAppCloudSwitch), + DECLARE_NAPI_STATIC_FUNCTION("clear", JsConfig::Clean), DECLARE_NAPI_STATIC_FUNCTION("clean", JsConfig::Clean), DECLARE_NAPI_STATIC_FUNCTION("notifyDataChange", JsConfig::NotifyDataChange), }; diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp index ea0bbe51..850cb693 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_const_properties.cpp @@ -46,6 +46,7 @@ napi_status InitConstProperties(napi_env env, napi_value exports) { const napi_property_descriptor properties[] = { DECLARE_NAPI_PROPERTY("Action", ExportAction(env)), + DECLARE_NAPI_PROPERTY("ClearAction", ExportAction(env)), }; size_t count = sizeof(properties) / sizeof(properties[0]); diff --git a/relational_store/frameworks/js/napi/cloud_data/src/napi_queue.cpp b/relational_store/frameworks/js/napi/cloud_data/src/napi_queue.cpp index 16eb9dd8..c3a18d87 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/napi_queue.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/napi_queue.cpp @@ -99,7 +99,8 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, env, nullptr, resource, [](napi_env env, void *data) { ASSERT_VOID(data != nullptr, "napi_async_execute_callback nullptr"); - auto actx = reinterpret_cast(data); + auto actx = static_cast(data); + ASSERT_VOID(actx->ctx != nullptr, "napi_async_execute_callback nullptr"); LOG_DEBUG("napi_async_execute_callback ctxt->status=%{public}d", actx->ctx->status); if (actx->execute && actx->ctx->status == napi_ok) { actx->execute(); @@ -107,7 +108,8 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, }, [](napi_env env, napi_status status, void *data) { ASSERT_VOID(data != nullptr, "napi_async_complete_callback nullptr"); - auto actx = reinterpret_cast(data); + auto actx = static_cast(data); + ASSERT_VOID(actx->ctx != nullptr, "napi_async_complete_callback nullptr"); LOG_DEBUG("napi_async_complete_callback status=%{public}d, ctxt->status=%{public}d", status, actx->ctx->status); if ((status != napi_ok) && (actx->ctx->status == napi_ok)) { diff --git a/relational_store/frameworks/js/napi/common/include/js_ability.h b/relational_store/frameworks/js/napi/common/include/js_ability.h index 72e41a65..91ca1e2b 100644 --- a/relational_store/frameworks/js/napi/common/include/js_ability.h +++ b/relational_store/frameworks/js/napi/common/include/js_ability.h @@ -32,7 +32,7 @@ public: explicit Context(std::shared_ptr abilityContext); std::string GetDatabaseDir(); - std::string GetPreferencesDir(); + int GetSystemDatabaseDir(const std::string &dataGroupId, std::string &databaseDir); std::string GetBundleName(); std::string GetModuleName(); std::string GetUri(); @@ -41,11 +41,11 @@ public: int32_t GetArea() const; bool IsSystemAppCalled(); bool IsHasProxyDataConfig() const; + bool IsStageMode() const; private: int32_t area_ = 0; std::string databaseDir_; - std::string preferencesDir_; std::string bundleName_; std::string moduleName_; std::string uri_; @@ -53,6 +53,8 @@ private: std::string writePermission_; bool hasProxyDataConfig_ = false; bool isSystemAppCalled_ = false; + bool isStageMode_ = false; + std::shared_ptr stageContext_; }; class JSAbility final { diff --git a/relational_store/frameworks/js/napi/common/mock/include/js_ability.h b/relational_store/frameworks/js/napi/common/mock/include/js_ability.h index 556108af..490fe2c3 100644 --- a/relational_store/frameworks/js/napi/common/mock/include/js_ability.h +++ b/relational_store/frameworks/js/napi/common/mock/include/js_ability.h @@ -35,7 +35,6 @@ public: #endif std::string GetDatabaseDir(); - std::string GetPreferencesDir(); std::string GetBundleName(); std::string GetModuleName(); std::string GetUri(); @@ -44,11 +43,12 @@ public: int32_t GetArea() const; bool IsSystemAppCalled(); bool IsHasProxyDataConfig() const; + int GetSystemDatabaseDir(const std::string &dataGroupId, std::string &databaseDir); + bool IsStageMode() const; private: int32_t area_ = 0; std::string databaseDir_; - std::string preferencesDir_; std::string bundleName_; std::string moduleName_; std::string uri_; @@ -56,6 +56,7 @@ private: std::string writePermission_; bool hasProxyDataConfig_ = false; bool isSystemAppCalled_ = false; + bool isStageMode_ = false; }; class JSAbility final { diff --git a/relational_store/frameworks/js/napi/common/mock/src/js_ability.cpp b/relational_store/frameworks/js/napi/common/mock/src/js_ability.cpp index f6c9b0bd..b1d9561b 100644 --- a/relational_store/frameworks/js/napi/common/mock/src/js_ability.cpp +++ b/relational_store/frameworks/js/napi/common/mock/src/js_ability.cpp @@ -33,7 +33,6 @@ Context::Context() baseDir = getenv("TEMP"); if (!baseDir.empty()) { databaseDir_ = baseDir + "\\HuaweiDevEcoStudioDatabases"; - preferencesDir_ = baseDir + "\\HuaweiDevEcoStudioPreferences"; } #endif @@ -42,7 +41,6 @@ Context::Context() baseDir = "/Users/" + baseDir + "/Library/Caches"; if (!baseDir.empty()) { databaseDir_ = baseDir + "/HuaweiDevEcoStudioDatabases"; - preferencesDir_ = baseDir + "/HuaweiDevEcoStudioPreferences"; } #endif bundleName_ = "com.example.myapplication"; @@ -51,7 +49,9 @@ Context::Context() #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM) Context::Context(std::shared_ptr stageContext) { - databaseDir_ = stageContext->GetDatabaseDir(); + if (stageContext != nullptr) { + databaseDir_ = stageContext->GetDatabaseDir(); + } } #endif @@ -60,11 +60,6 @@ std::string Context::GetDatabaseDir() return databaseDir_; } -std::string Context::GetPreferencesDir() -{ - return preferencesDir_; -} - std::string Context::GetBundleName() { return bundleName_; @@ -124,5 +119,16 @@ bool Context::IsHasProxyDataConfig() const { return hasProxyDataConfig_; } + +bool Context::IsStageMode() const +{ + return isStageMode_; +} + +int Context::GetSystemDatabaseDir(const std::string &dataGroupId, std::string &databaseDir) +{ + databaseDir = databaseDir_; + return 0; +} } // namespace AppDataMgrJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/common/src/js_ability.cpp b/relational_store/frameworks/js/napi/common/src/js_ability.cpp index dcc13d0e..23ee8624 100644 --- a/relational_store/frameworks/js/napi/common/src/js_ability.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_ability.cpp @@ -24,8 +24,9 @@ using namespace OHOS::Rdb; Context::Context(std::shared_ptr stageContext) { + this->stageContext_ = stageContext; + isStageMode_ = true; databaseDir_ = stageContext->GetDatabaseDir(); - preferencesDir_ = stageContext->GetPreferencesDir(); bundleName_ = stageContext->GetBundleName(); area_ = stageContext->GetArea(); auto hapInfo = stageContext->GetHapModuleInfo(); @@ -52,22 +53,17 @@ Context::Context(std::shared_ptr stageContext) } auto appInfo = stageContext->GetApplicationInfo(); isSystemAppCalled_ = appInfo == nullptr ? false : appInfo->isSystemApp; - LOG_DEBUG("Stage: area:%{public}d, bundleName:%{public}s, moduleName:%{public}s", area_, bundleName_.c_str(), - moduleName_.c_str()); } Context::Context(std::shared_ptr abilityContext) { databaseDir_ = abilityContext->GetDatabaseDir(); - preferencesDir_ = abilityContext->GetPreferencesDir(); bundleName_ = abilityContext->GetBundleName(); area_ = abilityContext->GetArea(); auto abilityInfo = abilityContext->GetAbilityInfo(); if (abilityInfo != nullptr) { moduleName_ = abilityInfo->moduleName; } - LOG_DEBUG("FA: area:%{public}d database:%{private}s preferences:%{private}s bundle:%{public}s hap:%{public}s", - area_, databaseDir_.c_str(), preferencesDir_.c_str(), bundleName_.c_str(), moduleName_.c_str()); } std::string Context::GetDatabaseDir() @@ -75,9 +71,9 @@ std::string Context::GetDatabaseDir() return databaseDir_; } -std::string Context::GetPreferencesDir() +int Context::GetSystemDatabaseDir(const std::string &dataGroupId, std::string &databaseDir) { - return preferencesDir_; + return stageContext_->GetSystemDatabaseDir(dataGroupId, false, databaseDir); } std::string Context::GetBundleName() @@ -116,6 +112,11 @@ bool Context::IsHasProxyDataConfig() const return hasProxyDataConfig_; } +bool Context::IsStageMode() const +{ + return isStageMode_; +} + bool JSAbility::CheckContext(napi_env env, napi_callback_info info) { size_t argc = 1; @@ -155,4 +156,4 @@ std::shared_ptr JSAbility::GetContext(napi_env env, napi_value value) return std::make_shared(abilityContext); } } // namespace AppDataMgrJsKit -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/common/src/js_utils.cpp b/relational_store/frameworks/js/napi/common/src/js_utils.cpp index 685d4c4b..0657ac44 100644 --- a/relational_store/frameworks/js/napi/common/src/js_utils.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_utils.cpp @@ -130,7 +130,7 @@ std::string JSUtils::ConvertAny2String(napi_env env, napi_value jsValue) napi_get_value_bool(env, jsValue, &valueBool); return std::to_string(valueBool); } else if (valueType == napi_null) { - return "null"; + return ""; } else if (valueType == napi_object) { std::vector bytes = JSUtils::Convert2U8Vector(env, jsValue); std::string ret(bytes.begin(), bytes.end()); diff --git a/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp b/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp index 100f80e3..74aa5565 100644 --- a/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp @@ -39,7 +39,6 @@ void UvQueue::AsyncCall(UvCallback callback, ArgsGenerator genArgs) LOG_ERROR("loop_ or callback is nullptr"); return; } - uv_work_t* work = new (std::nothrow) uv_work_t; if (work == nullptr) { LOG_ERROR("no memory for uv_work_t"); @@ -75,7 +74,6 @@ void UvQueue::AsyncCall(UvCallback callback, ArgsGenerator genArgs) argc = ARGC_MAX; entry->args(entry->env, argc, argv); } - LOG_DEBUG("queue uv_after_work_cb"); napi_value global = nullptr; napi_get_global(entry->env, &global); napi_value result; diff --git a/relational_store/frameworks/js/napi/dataability/include/napi_data_ability_predicates.h b/relational_store/frameworks/js/napi/dataability/include/napi_data_ability_predicates.h index d59bfd4e..9e15f9da 100644 --- a/relational_store/frameworks/js/napi/dataability/include/napi_data_ability_predicates.h +++ b/relational_store/frameworks/js/napi/dataability/include/napi_data_ability_predicates.h @@ -96,4 +96,4 @@ __attribute__((visibility("default"))) OHOS::NativeRdb::DataAbilityPredicates * NAPI_OHOS_Data_DataAbilityJsKit_DataAbilityPredicatesProxy_GetNativeObject( const napi_env &env, const napi_value &arg); EXTERN_C_END -#endif // DATAABILITY_JSKIT_NAPI_DATA_ABILITY_PREDICATES_H +#endif // DATAABILITY_JSKIT_NAPI_DATA_ABILITY_PREDICATES_H \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/dataability/include/napi_predicates_utils.h b/relational_store/frameworks/js/napi/dataability/include/napi_predicates_utils.h index 11e8678b..4c4ee48b 100644 --- a/relational_store/frameworks/js/napi/dataability/include/napi_predicates_utils.h +++ b/relational_store/frameworks/js/napi/dataability/include/napi_predicates_utils.h @@ -23,6 +23,13 @@ namespace OHOS { namespace DataAbilityJsKit { napi_value InitPredicatesUtils(napi_env env, napi_value info); +#define RDB_CHECK_RETURN_NULLPTR(assertion, message) \ + do { \ + if (!(assertion)) { \ + LOG_ERROR("%{public}s", message); \ + return nullptr; \ + } \ + } while (0) } // namespace DataAbilityJsKit } // namespace OHOS #endif // APPDATAMGR_NAPI_PREDICATES_UTILS_H diff --git a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp index 163ee0e1..d0138cf0 100644 --- a/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp +++ b/relational_store/frameworks/js/napi/dataability/src/napi_data_ability_predicates.cpp @@ -18,6 +18,7 @@ #include "js_utils.h" #include "logger.h" #include "napi_async_proxy.h" +#include "napi_predicates_utils.h" using namespace OHOS::Rdb; using namespace OHOS::NativeRdb; @@ -191,7 +192,9 @@ napi_value DataAbilityPredicatesProxy::EqualTo(napi_env env, napi_callback_info NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::EqualTo Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->EqualTo(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->EqualTo(field, value); return thiz; } @@ -204,7 +207,9 @@ napi_value DataAbilityPredicatesProxy::NotEqualTo(napi_env env, napi_callback_in NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::NotEqualTo Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->NotEqualTo(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->NotEqualTo(field, value); return thiz; } @@ -212,7 +217,9 @@ napi_value DataAbilityPredicatesProxy::BeginWrap(napi_env env, napi_callback_inf { napi_value thiz; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->BeginWrap(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->BeginWrap(); return thiz; } @@ -220,7 +227,9 @@ napi_value DataAbilityPredicatesProxy::EndWrap(napi_env env, napi_callback_info { napi_value thiz; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->EndWrap(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->EndWrap(); return thiz; } @@ -228,7 +237,9 @@ napi_value DataAbilityPredicatesProxy::Or(napi_env env, napi_callback_info info) { napi_value thiz; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Or(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Or(); return thiz; } @@ -236,7 +247,9 @@ napi_value DataAbilityPredicatesProxy::And(napi_env env, napi_callback_info info { napi_value thiz; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->And(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->And(); return thiz; } @@ -249,8 +262,9 @@ napi_value DataAbilityPredicatesProxy::Contains(napi_env env, napi_callback_info NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::Contains Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - - GetNativePredicates(env, info)->Contains(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Contains(field, value); return thiz; } @@ -263,7 +277,9 @@ napi_value DataAbilityPredicatesProxy::BeginsWith(napi_env env, napi_callback_in NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::BeginsWith Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->BeginsWith(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->BeginsWith(field, value); return thiz; } @@ -276,7 +292,9 @@ napi_value DataAbilityPredicatesProxy::EndsWith(napi_env env, napi_callback_info NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::EndsWith Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->EndsWith(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->EndsWith(field, value); return thiz; } @@ -288,7 +306,9 @@ napi_value DataAbilityPredicatesProxy::IsNull(napi_env env, napi_callback_info i napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::IsNull Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->IsNull(field); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->IsNull(field); return thiz; } @@ -300,7 +320,9 @@ napi_value DataAbilityPredicatesProxy::IsNotNull(napi_env env, napi_callback_inf napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::IsNotNull Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->IsNotNull(field); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->IsNotNull(field); return thiz; } @@ -313,7 +335,9 @@ napi_value DataAbilityPredicatesProxy::Like(napi_env env, napi_callback_info inf NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::Like Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->Like(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Like(field, value); return thiz; } @@ -326,7 +350,9 @@ napi_value DataAbilityPredicatesProxy::Glob(napi_env env, napi_callback_info inf NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::Glob Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->Glob(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Glob(field, value); return thiz; } @@ -340,7 +366,9 @@ napi_value DataAbilityPredicatesProxy::Between(napi_env env, napi_callback_info std::string field = JSUtils::Convert2String(env, args[0]); std::string low = JSUtils::ConvertAny2String(env, args[1]); std::string high = JSUtils::ConvertAny2String(env, args[2]); - GetNativePredicates(env, info)->Between(field, low, high); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Between(field, low, high); return thiz; } @@ -354,7 +382,9 @@ napi_value DataAbilityPredicatesProxy::NotBetween(napi_env env, napi_callback_in std::string field = JSUtils::Convert2String(env, args[0]); std::string low = JSUtils::ConvertAny2String(env, args[1]); std::string high = JSUtils::ConvertAny2String(env, args[2]); - GetNativePredicates(env, info)->NotBetween(field, low, high); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->NotBetween(field, low, high); return thiz; } @@ -367,7 +397,9 @@ napi_value DataAbilityPredicatesProxy::GreaterThan(napi_env env, napi_callback_i NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::GreaterThan Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->GreaterThan(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->GreaterThan(field, value); return thiz; } @@ -380,7 +412,9 @@ napi_value DataAbilityPredicatesProxy::LessThan(napi_env env, napi_callback_info NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::LessThan Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->LessThan(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->LessThan(field, value); return thiz; } @@ -393,7 +427,9 @@ napi_value DataAbilityPredicatesProxy::GreaterThanOrEqualTo(napi_env env, napi_c NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::GreaterThanOrEqualTo Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->GreaterThanOrEqualTo(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->GreaterThanOrEqualTo(field, value); return thiz; } @@ -406,7 +442,9 @@ napi_value DataAbilityPredicatesProxy::LessThanOrEqualTo(napi_env env, napi_call NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::LessThanOrEqualTo Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::string value = JSUtils::ConvertAny2String(env, args[1]); - GetNativePredicates(env, info)->LessThanOrEqualTo(field, value); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->LessThanOrEqualTo(field, value); return thiz; } @@ -418,7 +456,9 @@ napi_value DataAbilityPredicatesProxy::OrderByAsc(napi_env env, napi_callback_in napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::OrderByAsc Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->OrderByAsc(field); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->OrderByAsc(field); return thiz; } @@ -430,7 +470,9 @@ napi_value DataAbilityPredicatesProxy::OrderByDesc(napi_env env, napi_callback_i napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::OrderByDesc Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->OrderByDesc(field); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->OrderByDesc(field); return thiz; } @@ -438,7 +480,9 @@ napi_value DataAbilityPredicatesProxy::Distinct(napi_env env, napi_callback_info { napi_value thiz; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Distinct(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Distinct(); return thiz; } @@ -451,7 +495,9 @@ napi_value DataAbilityPredicatesProxy::Limit(napi_env env, napi_callback_info in NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::Limit Invalid argvs!"); int32_t limit = 0; napi_get_value_int32(env, args[0], &limit); - GetNativePredicates(env, info)->Limit(limit); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Limit(limit); return thiz; } @@ -464,7 +510,9 @@ napi_value DataAbilityPredicatesProxy::Offset(napi_env env, napi_callback_info i NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::Offset Invalid argvs!"); int32_t offset = 0; napi_get_value_int32(env, args[0], &offset); - GetNativePredicates(env, info)->Offset(offset); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Offset(offset); return thiz; } @@ -476,7 +524,9 @@ napi_value DataAbilityPredicatesProxy::GroupBy(napi_env env, napi_callback_info napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::GroupBy Invalid argvs!"); std::vector fields = JSUtils::Convert2StrVector(env, args[0]); - GetNativePredicates(env, info)->GroupBy(fields); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->GroupBy(fields); return thiz; } @@ -488,7 +538,9 @@ napi_value DataAbilityPredicatesProxy::IndexedBy(napi_env env, napi_callback_inf napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::IndexedBy Invalid argvs!"); std::string indexName = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->IndexedBy(indexName); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->IndexedBy(indexName); return thiz; } @@ -501,7 +553,9 @@ napi_value DataAbilityPredicatesProxy::In(napi_env env, napi_callback_info info) NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::In Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::vector values = JSUtils::Convert2StrVector(env, args[1]); - GetNativePredicates(env, info)->In(field, values); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->In(field, values); return thiz; } @@ -514,7 +568,9 @@ napi_value DataAbilityPredicatesProxy::NotIn(napi_env env, napi_callback_info in NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::NotIn Invalid argvs!"); std::string field = JSUtils::Convert2String(env, args[0]); std::vector values = JSUtils::Convert2StrVector(env, args[1]); - GetNativePredicates(env, info)->NotIn(field, values); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->NotIn(field, values); return thiz; } @@ -522,7 +578,9 @@ napi_value DataAbilityPredicatesProxy::Clear(napi_env env, napi_callback_info in { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Clear(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Clear(); return thiz; } @@ -530,7 +588,9 @@ napi_value DataAbilityPredicatesProxy::IsRawSelection(napi_env env, napi_callbac { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - bool out = GetNativePredicates(env, info)->IsRawSelection(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + bool out = nativePredicates->IsRawSelection(); return JSUtils::Convert2JSValue(env, out); } @@ -541,7 +601,9 @@ std::shared_ptr DataAbilityPredicatesProxy::Ge napi_value DataAbilityPredicatesProxy::GetWhereClause(napi_env env, napi_callback_info info) { - auto ret = GetNativePredicates(env, info)->GetWhereClause(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto ret = nativePredicates->GetWhereClause(); return JSUtils::Convert2JSValue(env, ret); } @@ -554,14 +616,18 @@ napi_value DataAbilityPredicatesProxy::SetWhereClause(napi_env env, napi_callbac NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::SetWhereClause Invalid argvs!"); std::string whereClause = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->SetWhereClause(whereClause); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->SetWhereClause(whereClause); return thiz; } napi_value DataAbilityPredicatesProxy::GetWhereArgs(napi_env env, napi_callback_info info) { - auto ret = GetNativePredicates(env, info)->GetWhereArgs(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto ret = nativePredicates->GetWhereArgs(); return JSUtils::Convert2JSValue(env, ret); } @@ -574,14 +640,18 @@ napi_value DataAbilityPredicatesProxy::SetWhereArgs(napi_env env, napi_callback_ NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::SetWhereArgs Invalid argvs!"); std::vector whereArgs = JSUtils::Convert2StrVector(env, args[0]); - GetNativePredicates(env, info)->SetWhereArgs(whereArgs); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->SetWhereArgs(whereArgs); return thiz; } napi_value DataAbilityPredicatesProxy::GetOrder(napi_env env, napi_callback_info info) { - auto ret = GetNativePredicates(env, info)->GetOrder(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto ret = nativePredicates->GetOrder(); return JSUtils::Convert2JSValue(env, ret); } @@ -594,46 +664,62 @@ napi_value DataAbilityPredicatesProxy::SetOrder(napi_env env, napi_callback_info NAPI_ASSERT(env, argc > 0, "DataAbilityPredicatesProxy::SetOrder Invalid argvs!"); std::string order = JSUtils::Convert2String(env, args[0]); - GetNativePredicates(env, info)->SetOrder(order); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->SetOrder(order); return thiz; } napi_value DataAbilityPredicatesProxy::GetLimit(napi_env env, napi_callback_info info) { - return JSUtils::Convert2JSValue(env, GetNativePredicates(env, info)->GetLimit()); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + return JSUtils::Convert2JSValue(env, nativePredicates->GetLimit()); } napi_value DataAbilityPredicatesProxy::GetOffset(napi_env env, napi_callback_info info) { - return JSUtils::Convert2JSValue(env, GetNativePredicates(env, info)->GetOffset()); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + return JSUtils::Convert2JSValue(env, nativePredicates->GetOffset()); } napi_value DataAbilityPredicatesProxy::IsDistinct(napi_env env, napi_callback_info info) { - return JSUtils::Convert2JSValue(env, GetNativePredicates(env, info)->IsDistinct()); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + return JSUtils::Convert2JSValue(env, nativePredicates->IsDistinct()); } napi_value DataAbilityPredicatesProxy::GetGroup(napi_env env, napi_callback_info info) { - auto ret = GetNativePredicates(env, info)->GetGroup(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto ret = nativePredicates->GetGroup(); return JSUtils::Convert2JSValue(env, ret); } napi_value DataAbilityPredicatesProxy::GetIndex(napi_env env, napi_callback_info info) { - auto ret = GetNativePredicates(env, info)->GetIndex(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto ret = nativePredicates->GetIndex(); return JSUtils::Convert2JSValue(env, ret); } napi_value DataAbilityPredicatesProxy::IsNeedAnd(napi_env env, napi_callback_info info) { - return JSUtils::Convert2JSValue(env, GetNativePredicates(env, info)->IsNeedAnd()); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + return JSUtils::Convert2JSValue(env, nativePredicates->IsNeedAnd()); } napi_value DataAbilityPredicatesProxy::IsSorted(napi_env env, napi_callback_info info) { - return JSUtils::Convert2JSValue(env, GetNativePredicates(env, info)->IsSorted()); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + return JSUtils::Convert2JSValue(env, nativePredicates->IsSorted()); } } // namespace DataAbilityJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h index 19578ca7..4b81bc0a 100644 --- a/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h +++ b/relational_store/frameworks/js/napi/rdb/include/napi_rdb_error.h @@ -52,6 +52,8 @@ constexpr int E_RESULT_GOTO_ERROR = 14800012; } \ } while (0) +#define RDB_REVT_NOTHING + #define RDB_NAPI_ASSERT_FROMV9(env, assertion, error, version) \ RDB_NAPI_ASSERT_BASE_FROMV9(env, assertion, error, nullptr, version) @@ -66,13 +68,33 @@ constexpr int E_RESULT_GOTO_ERROR = 14800012; } \ } while (0) -#define RDB_CHECK_RETURN_NULLPTR(assertion) \ - do { \ - if (!(assertion)) { \ - return nullptr; \ - } \ +#define RDB_CHECK_RETURN_NULLPTR(assertion, message) \ + do { \ + if (!(assertion)) { \ + LOG_ERROR("%{public}s", message); \ + return nullptr; \ + } \ + } while (0) + +#define RDB_CHECK_RETURN_VOID(assertion, message) \ + do { \ + if (!(assertion)) { \ + LOG_ERROR("%{public}s", message); \ + return; \ + } \ } while (0) +#define CHECK_RETURN_CORE(assertion, theCall, revt) \ + do { \ + if (!(assertion)) { \ + theCall; \ + return revt; \ + } \ + } while (0) + +#define CHECK_RETURN_ERR(assertion) \ + CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, ERR) + #define RDB_CHECK_RETURN_CALL_RESULT(assertion, theCall) \ do { \ if (!(assertion)) { \ diff --git a/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h b/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h index 403844c6..26fa2475 100644 --- a/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h +++ b/relational_store/frameworks/js/napi/rdb/include/napi_result_set.h @@ -90,12 +90,4 @@ private: }; } // namespace RdbJsKit } // namespace OHOS -#endif // RDB_JSKIT_NAPI_RESULT_SET_H - -EXTERN_C_START -__attribute__((visibility("default"))) napi_value NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_NewInstance( - napi_env env, OHOS::NativeRdb::AbsSharedResultSet *resultSet); - -__attribute__((visibility("default"))) OHOS::NativeRdb::AbsSharedResultSet * -NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_GetNativeObject(const napi_env &env, const napi_value &arg); -EXTERN_C_END \ No newline at end of file +#endif // RDB_JSKIT_NAPI_RESULT_SET_H \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp index ed7ebbbd..916d2d5d 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_async_call.cpp @@ -111,7 +111,7 @@ void AsyncCall::OnExecute(napi_env env, void *data) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); BaseContext *context = reinterpret_cast(data); - if (context->exec_) { + if (context && context->exec_) { context->execStatus = context->exec_(); context->exec_ = nullptr; } @@ -124,6 +124,9 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) napi_value output = nullptr; int outStatus = ERR; // if async execute status is not napi_ok then un-execute out function + if (context == nullptr) { + return; + } if ((context->execStatus == OK) && context->output_) { outStatus = context->output_(env, output); } diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp index 4d24dcc8..036482f1 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_predicates.cpp @@ -164,6 +164,7 @@ napi_value RdbPredicatesProxy::NewInstance(napi_env env, std::shared_ptrGetTableName()) }; napi_value instance = nullptr; status = napi_new_instance(env, cons, argc, args, &instance); @@ -333,7 +334,8 @@ napi_value RdbPredicatesProxy::EqualTo(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->EqualTo(field, value); return thiz; } @@ -344,7 +346,8 @@ napi_value RdbPredicatesProxy::NotEqualTo(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->NotEqualTo(field, value); return thiz; } @@ -353,7 +356,9 @@ napi_value RdbPredicatesProxy::BeginWrap(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->BeginWrap(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->BeginWrap(); return thiz; } @@ -361,7 +366,9 @@ napi_value RdbPredicatesProxy::EndWrap(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->EndWrap(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->EndWrap(); return thiz; } @@ -369,7 +376,9 @@ napi_value RdbPredicatesProxy::Or(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Or(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Or(); return thiz; } @@ -377,7 +386,9 @@ napi_value RdbPredicatesProxy::And(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->And(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->And(); return thiz; } @@ -387,7 +398,8 @@ napi_value RdbPredicatesProxy::Contains(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Contains(field, value); return thiz; } @@ -398,7 +410,8 @@ napi_value RdbPredicatesProxy::BeginsWith(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->BeginsWith(field, value); return thiz; } @@ -409,7 +422,8 @@ napi_value RdbPredicatesProxy::EndsWith(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->EndsWith(field, value); return thiz; } @@ -419,7 +433,8 @@ napi_value RdbPredicatesProxy::IsNull(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string field = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, field, "field"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->IsNull(field); return thiz; } @@ -429,7 +444,8 @@ napi_value RdbPredicatesProxy::IsNotNull(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string field = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, field, "field"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->IsNotNull(field); return thiz; } @@ -440,7 +456,8 @@ napi_value RdbPredicatesProxy::Like(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Like(field, value); return thiz; } @@ -451,7 +468,8 @@ napi_value RdbPredicatesProxy::Glob(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Glob(field, value); return thiz; } @@ -463,7 +481,8 @@ napi_value RdbPredicatesProxy::Between(napi_env env, napi_callback_info info) std::string low = ""; std::string high = ""; auto predicatesProxy = ParseFieldLowAndHigh(env, info, thiz, field, low, high); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Between(field, low, high); return thiz; } @@ -475,7 +494,8 @@ napi_value RdbPredicatesProxy::NotBetween(napi_env env, napi_callback_info info) std::string low = ""; std::string high = ""; auto predicatesProxy = ParseFieldLowAndHigh(env, info, thiz, field, low, high); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->NotBetween(field, low, high); return thiz; } @@ -486,7 +506,8 @@ napi_value RdbPredicatesProxy::GreaterThan(napi_env env, napi_callback_info info std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->GreaterThan(field, value); return thiz; } @@ -497,7 +518,8 @@ napi_value RdbPredicatesProxy::LessThan(napi_env env, napi_callback_info info) std::string field = ""; std::string value = ""; auto predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->LessThan(field, value); return thiz; } @@ -508,7 +530,8 @@ napi_value RdbPredicatesProxy::GreaterThanOrEqualTo(napi_env env, napi_callback_ std::string field = ""; std::string value = ""; RdbPredicatesProxy *predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->GreaterThanOrEqualTo(field, value); return thiz; } @@ -519,7 +542,8 @@ napi_value RdbPredicatesProxy::LessThanOrEqualTo(napi_env env, napi_callback_inf std::string field = ""; std::string value = ""; RdbPredicatesProxy *predicatesProxy = ParseFieldAndValue(env, info, thiz, field, value, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->LessThanOrEqualTo(field, value); return thiz; } @@ -529,7 +553,8 @@ napi_value RdbPredicatesProxy::OrderByAsc(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string field = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, field, "field"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->OrderByAsc(field); return thiz; } @@ -539,7 +564,8 @@ napi_value RdbPredicatesProxy::OrderByDesc(napi_env env, napi_callback_info info napi_value thiz = nullptr; std::string field = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, field, "field"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->OrderByDesc(field); return thiz; } @@ -548,7 +574,9 @@ napi_value RdbPredicatesProxy::Distinct(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Distinct(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Distinct(); return thiz; } @@ -557,7 +585,8 @@ napi_value RdbPredicatesProxy::Limit(napi_env env, napi_callback_info info) napi_value thiz = nullptr; int32_t limit = 0; auto predicatesProxy = ParseInt32FieldByName(env, info, thiz, limit, "value"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Limit(limit); return thiz; } @@ -567,7 +596,8 @@ napi_value RdbPredicatesProxy::Offset(napi_env env, napi_callback_info info) napi_value thiz = nullptr; int32_t offset = 0; auto predicatesProxy = ParseInt32FieldByName(env, info, thiz, offset, "rowOffset"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Offset(offset); return thiz; } @@ -578,7 +608,8 @@ napi_value RdbPredicatesProxy::GroupBy(napi_env env, napi_callback_info info) std::string field = ""; std::vector fields; auto predicatesProxy = ParseFieldArrayByName(env, info, thiz, fields, "fields", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->GroupBy(fields); return thiz; } @@ -588,7 +619,8 @@ napi_value RdbPredicatesProxy::IndexedBy(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string indexName = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, indexName, "fields"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->IndexedBy(indexName); return thiz; } @@ -599,7 +631,8 @@ napi_value RdbPredicatesProxy::In(napi_env env, napi_callback_info info) std::string field = ""; std::vector values; auto predicatesProxy = ParseFieldAndValueArray(env, info, thiz, field, values, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->In(field, values); return thiz; } @@ -610,7 +643,8 @@ napi_value RdbPredicatesProxy::NotIn(napi_env env, napi_callback_info info) std::string field = ""; std::vector values; auto predicatesProxy = ParseFieldAndValueArray(env, info, thiz, field, values, "ValueType"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->NotIn(field, values); return thiz; } @@ -620,7 +654,8 @@ napi_value RdbPredicatesProxy::Using(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::vector fields; auto predicatesProxy = ParseFieldArrayByName(env, info, thiz, fields, "fields", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->Using(fields); return thiz; } @@ -630,7 +665,8 @@ napi_value RdbPredicatesProxy::LeftOuterJoin(napi_env env, napi_callback_info in napi_value thiz = nullptr; std::string tablename = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, tablename, "tablename"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->LeftOuterJoin(tablename); return thiz; } @@ -640,7 +676,8 @@ napi_value RdbPredicatesProxy::InnerJoin(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string tablename = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, tablename, "tablename"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->InnerJoin(tablename); return thiz; } @@ -650,7 +687,8 @@ napi_value RdbPredicatesProxy::On(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::vector clauses; auto predicatesProxy = ParseFieldArrayByName(env, info, thiz, clauses, "clauses", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->On(clauses); return thiz; } @@ -659,7 +697,9 @@ napi_value RdbPredicatesProxy::Clear(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->Clear(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->Clear(); return thiz; } @@ -668,7 +708,8 @@ napi_value RdbPredicatesProxy::CrossJoin(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::string tablename = ""; auto predicatesProxy = ParseFieldByName(env, info, thiz, tablename, "tablename"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->CrossJoin(tablename); return thiz; } @@ -677,7 +718,9 @@ napi_value RdbPredicatesProxy::GetJoinCount(napi_env env, napi_callback_info inf { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - int errCode = GetNativePredicates(env, info)->GetJoinCount(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + int errCode = nativePredicates->GetJoinCount(); return JSUtils::Convert2JSValue(env, errCode); } @@ -686,7 +729,8 @@ napi_value RdbPredicatesProxy::SetJoinCount(napi_env env, napi_callback_info inf napi_value thiz; int32_t joinCount = 0; RdbPredicatesProxy *predicatesProxy = ParseInt32FieldByName(env, info, thiz, joinCount, "joinCount"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->SetJoinCount(joinCount); return thiz; } @@ -695,7 +739,9 @@ napi_value RdbPredicatesProxy::GetJoinTypes(napi_env env, napi_callback_info inf { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - auto joinTypes = GetNativePredicates(env, info)->GetJoinTypes(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto joinTypes = nativePredicates->GetJoinTypes(); return JSUtils::Convert2JSValue(env, joinTypes); } @@ -703,7 +749,9 @@ napi_value RdbPredicatesProxy::GetJoinTableNames(napi_env env, napi_callback_inf { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - auto joinTableNames = GetNativePredicates(env, info)->GetJoinTableNames(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto joinTableNames = nativePredicates->GetJoinTableNames(); return JSUtils::Convert2JSValue(env, joinTableNames); ; } @@ -712,7 +760,9 @@ napi_value RdbPredicatesProxy::GetJoinConditions(napi_env env, napi_callback_inf { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - auto joinConditions = GetNativePredicates(env, info)->GetJoinConditions(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + auto joinConditions = nativePredicates->GetJoinConditions(); return JSUtils::Convert2JSValue(env, joinConditions); } @@ -722,7 +772,8 @@ napi_value RdbPredicatesProxy::SetJoinConditions(napi_env env, napi_callback_inf std::vector joinConditions; RdbPredicatesProxy *predicatesProxy = ParseFieldArrayByName(env, info, thiz, joinConditions, "joinConditions", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->SetJoinConditions(joinConditions); return thiz; } @@ -732,7 +783,8 @@ napi_value RdbPredicatesProxy::SetJoinTableNames(napi_env env, napi_callback_inf napi_value thiz = nullptr; std::vector joinNames; RdbPredicatesProxy *predicatesProxy = ParseFieldArrayByName(env, info, thiz, joinNames, "joinNames", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->SetJoinTableNames(joinNames); return thiz; } @@ -742,7 +794,8 @@ napi_value RdbPredicatesProxy::SetJoinTypes(napi_env env, napi_callback_info inf napi_value thiz = nullptr; std::vector joinTypes; RdbPredicatesProxy *predicatesProxy = ParseFieldArrayByName(env, info, thiz, joinTypes, "joinTypes", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->SetJoinTypes(joinTypes); return thiz; } @@ -758,7 +811,8 @@ napi_value RdbPredicatesProxy::InDevices(napi_env env, napi_callback_info info) napi_value thiz = nullptr; std::vector devices; RdbPredicatesProxy *predicatesProxy = ParseFieldArrayByName(env, info, thiz, devices, "devices", "string"); - RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(predicatesProxy != nullptr && predicatesProxy->predicates_ != nullptr, + "RdbPredicatesProxy predicatesProxy or predicates_ is nullptr"); predicatesProxy->predicates_->InDevices(devices); return thiz; } @@ -767,7 +821,9 @@ napi_value RdbPredicatesProxy::InAllDevices(napi_env env, napi_callback_info inf { napi_value thiz = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); - GetNativePredicates(env, info)->InAllDevices(); + auto nativePredicates = GetNativePredicates(env, info); + RDB_CHECK_RETURN_NULLPTR(nativePredicates != nullptr, "GetNativePredicates return nullptr"); + nativePredicates->InAllDevices(); return thiz; } #endif diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp index a6b0ae04..cc0c032e 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp @@ -359,7 +359,8 @@ int ParsePredicates(const napi_env &env, const napi_value &arg, std::shared_ptr< || CheckGlobalProperty(env, arg, "RdbPredicatesConstructorV9")) { LOG_DEBUG("Parse RDB Predicates"); napi_unwrap(env, arg, reinterpret_cast(&context->predicatesProxy)); - RDB_CHECK_RETURN_CALL_RESULT(context->predicatesProxy != nullptr, context->SetError(paramError)); + RDB_CHECK_RETURN_CALL_RESULT(context->predicatesProxy != nullptr && + context->predicatesProxy->GetPredicates() != nullptr, context->SetError(paramError)); context->tableName = context->predicatesProxy->GetPredicates()->GetTableName(); context->rdbPredicates = context->predicatesProxy->GetPredicates(); LOG_DEBUG("ParsePredicates end"); @@ -568,6 +569,7 @@ napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int64_t rowId = 0; LOG_DEBUG("RdbStoreProxy::Insert Async"); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->Insert(rowId, context->tableName, context->valuesBucket); context->rowId = rowId; LOG_DEBUG("RdbStoreProxy::Insert errCode is: %{public}d", errCode); @@ -580,7 +582,7 @@ napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -604,6 +606,7 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) return E_OK; } int64_t outInsertNum = 0; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->BatchInsert(outInsertNum, context->tableName, context->valuesBuckets); context->insertNum = outInsertNum; return (errCode == E_OK) ? OK : ERR; @@ -615,7 +618,7 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -642,6 +645,7 @@ napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) LOG_DEBUG("RdbStoreProxy::Delete Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int deletedRows = 0; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->Delete(deletedRows, *(context->rdbPredicates)); context->rowId = deletedRows; LOG_DEBUG("RdbStoreProxy::Delete errCode is: %{public}d", errCode); @@ -654,7 +658,7 @@ napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -684,6 +688,7 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) LOG_DEBUG("RdbStoreProxy::Update Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int changedRows = 0; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->Update(changedRows, context->valuesBucket, *(context->rdbPredicates)); context->rowId = changedRows; LOG_DEBUG("RdbStoreProxy::Update errCode is: %{public}d", errCode); @@ -696,7 +701,7 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -727,6 +732,7 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) }; auto exec = [context]() { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->resultSet = obj->rdbStore_->Query(*(context->rdbPredicates), context->columns); LOG_DEBUG("RdbStoreProxy::Query result is nullptr ? %{public}d", (context->resultSet == nullptr)); return (context->resultSet != nullptr) ? OK : ERR; @@ -738,7 +744,7 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -763,6 +769,7 @@ napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) auto exec = [context]() { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->resultSet = obj->rdbStore_->QueryByStep(context->sql, context->columns); LOG_ERROR("RdbStoreProxy::QuerySql is nullptr ? %{public}d ", context->resultSet == nullptr); return (context->resultSet != nullptr) ? OK : ERR; @@ -782,7 +789,7 @@ napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -809,6 +816,7 @@ napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::ExecuteSql Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->ExecuteSql(context->sql, context->bindArgs); LOG_DEBUG("RdbStoreProxy::ExecuteSql errCode is: %{public}d", errCode); return (errCode == E_OK) ? OK : ERR; @@ -820,7 +828,7 @@ napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -839,6 +847,9 @@ napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) LOG_DEBUG("RdbStoreProxy::Count Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); std::int64_t temp = 0; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->predicatesProxy != nullptr && + context->predicatesProxy->GetPredicates() != nullptr); int errCode = obj->rdbStore_->Count(temp, *(context->predicatesProxy->GetPredicates())); context->rowId = temp; LOG_DEBUG("RdbStoreProxy::Count errCode is: %{public}d", errCode); @@ -851,7 +862,7 @@ napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -872,6 +883,7 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) LOG_DEBUG("RdbStoreProxy::Replace Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int64_t rowId = 0; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->Replace(rowId, context->tableName, context->valuesBucket); context->rowId = rowId; LOG_DEBUG("RdbStoreProxy::Replace errCode is:%{public}d", errCode); @@ -884,7 +896,7 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -904,6 +916,7 @@ napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::Attach Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); int errCode = obj->rdbStore_->Attach(context->aliasName, context->pathName, context->newKey); LOG_ERROR("RdbStoreProxy::Attach errCode is:%{public}d ", errCode); return (errCode != E_OK) ? OK : ERR; @@ -915,7 +928,7 @@ napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -924,7 +937,8 @@ napi_value RdbStoreProxy::IsHoldingConnection(napi_env env, napi_callback_info i napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, rdbStoreProxy != nullptr && + rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr"); bool out = rdbStoreProxy->rdbStore_->IsHoldingConnection(); LOG_DEBUG("RdbStoreProxy::IsHoldingConnection out is : %{public}d", out); return JSUtils::Convert2JSValue(env, out); @@ -935,7 +949,8 @@ napi_value RdbStoreProxy::IsReadOnly(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, rdbStoreProxy != nullptr + && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr"); bool out = rdbStoreProxy->rdbStore_->IsReadOnly(); LOG_DEBUG("RdbStoreProxy::IsReadOnly out is : %{public}d", out); return JSUtils::Convert2JSValue(env, out); @@ -946,7 +961,8 @@ napi_value RdbStoreProxy::IsMemoryRdb(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, rdbStoreProxy != nullptr + && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr"); bool out = rdbStoreProxy->rdbStore_->IsMemoryRdb(); LOG_DEBUG("RdbStoreProxy::IsMemoryRdb out is : %{public}d", out); return JSUtils::Convert2JSValue(env, out); @@ -957,7 +973,8 @@ napi_value RdbStoreProxy::GetPath(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, rdbStoreProxy != nullptr + && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr"); std::string path = rdbStoreProxy->rdbStore_->GetPath(); LOG_DEBUG("RdbStoreProxy::GetPath path is empty ? %{public}d", path.empty()); return JSUtils::Convert2JSValue(env, path); @@ -968,7 +985,8 @@ napi_value RdbStoreProxy::BeginTransaction(napi_env env, napi_callback_info info napi_value thisObj = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr)); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, rdbStoreProxy != nullptr + && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr"); int errCode = rdbStoreProxy->rdbStore_->BeginTransaction(); NAPI_ASSERT(env, errCode == E_OK, "call BeginTransaction failed"); LOG_DEBUG("RdbStoreProxy::BeginTransaction end, errCode is:%{public}d", errCode); @@ -1015,6 +1033,9 @@ napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info) auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::QueryByStep Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + if (obj == nullptr || obj->rdbStore_ == nullptr) { + return ERR; + } context->stepResultSet = obj->rdbStore_->QueryByStep(context->sql, context->columns); LOG_ERROR("RdbStoreProxy::QueryByStep is nullptr ? %{public}d ", context->stepResultSet == nullptr); return (context->stepResultSet != nullptr) ? OK : ERR; @@ -1028,7 +1049,7 @@ napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -1048,7 +1069,7 @@ napi_value RdbStoreProxy::IsOpen(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr"); bool out = rdbStoreProxy->rdbStore_->IsOpen(); LOG_DEBUG("RdbStoreProxy::IsOpen out is : %{public}d", out); return JSUtils::Convert2JSValue(env, out); @@ -1059,7 +1080,7 @@ napi_value RdbStoreProxy::GetVersion(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr"); int32_t version = 0; int out = rdbStoreProxy->rdbStore_->GetVersion(version); LOG_DEBUG("RdbStoreProxy::GetVersion out is : %{public}d", out); @@ -1074,7 +1095,7 @@ napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info) napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); NAPI_ASSERT(env, argc == 1, "RdbStoreProxy::SetVersion Invalid argvs!"); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thiz); - NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr"); + NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr"); int32_t version = 0; napi_get_value_int32(env, args[0], &version); int out = rdbStoreProxy->rdbStore_->SetVersion(version); @@ -1097,6 +1118,9 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info auto exec = [context]() { LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + if (obj == nullptr || obj->rdbStore_.get() == nullptr) { + return ERR; + } int res = obj->rdbStore_->SetDistributedTables(context->tablesName); LOG_DEBUG("RdbStoreProxy::SetDistributedTables res is : %{public}d", res); return (res == E_OK || res == E_NOT_SUPPORTED) ? OK : ERR; @@ -1108,7 +1132,7 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -1128,6 +1152,9 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int errCode = E_ERROR; + if (obj == nullptr || obj->rdbStore_.get() == nullptr) { + return ERR; + } auto name = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName, errCode); LOG_INFO("RdbStoreProxy::ObtainDistributedTableName name is empty ? : %{public}d, errCode is %{public}d", name.empty(), errCode); @@ -1142,7 +1169,7 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -1164,6 +1191,9 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) SyncOption option; option.mode = static_cast(context->enumArg); option.isBlock = true; + if (obj == nullptr || obj->rdbStore_.get() == nullptr) { + return ERR; + } int res = obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), [context](const SyncResult &result) { context->syncResult = result; }); LOG_INFO("RdbStoreProxy::Sync res is : %{public}d", res); @@ -1176,7 +1206,7 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, ""); return AsyncCall::Call(env, context); } @@ -1204,7 +1234,7 @@ void RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *arg std::lock_guard lockGuard(mutex_); for (const auto &observer : observers_[mode]) { - if (*observer == argv[1]) { + if (observer != nullptr && *observer == argv[1]) { LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: duplicate subscribe"); return; } @@ -1247,7 +1277,11 @@ void RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *ar option.mode = static_cast(mode); std::lock_guard lockGuard(mutex_); for (auto it = observers_[mode].begin(); it != observers_[mode].end(); it++) { - if (**it == argv[1]) { + if (*it != nullptr && **it == argv[1]) { + if (rdbStore_.get() == nullptr) { + LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: rdbStore_ invalid"); + return; + } rdbStore_->UnSubscribe(option, it->get()); observers_[mode].erase(it); LOG_INFO("RdbStoreProxy::OffDataChangeEvent: unsubscribe success"); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_helper.cpp index 3e5f027a..8e44a5cb 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_helper.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_helper.cpp @@ -471,7 +471,8 @@ napi_value InnerGetRdbStore(napi_env env, napi_callback_info info, std::shared_p }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, + "RdbJsKit::GetRdbStore end with err"); return AsyncCall::Call(env, context); } @@ -524,7 +525,8 @@ napi_value InnerDeleteRdbStore(napi_env env, napi_callback_info info, std::share }; context->SetAction(env, info, input, exec, output); - RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK); + RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, + "RdbJsKit::DeleteRdbStore end with err"); return AsyncCall::Call(env, context); } diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_observer.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_observer.cpp index 14f69bcf..ca46ae7f 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_observer.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store_observer.cpp @@ -37,6 +37,10 @@ void NapiRdbStoreObserver::OnChange(const std::vector &devices) LOG_INFO("NapiRdbStoreObserver::OnChange begin"); CallFunction([devices](napi_env env, int &argc, napi_value *argv) { argc = 1; + if (argv == nullptr) { + LOG_ERROR("NapiRdbStoreObserver::CallFunction error"); + return; + } argv[0] = JSUtils::Convert2JSValue(env, devices); }); LOG_INFO("NapiRdbStoreObserver::OnChange end"); diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp index 758f70a3..4fa7cb92 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_result_set.cpp @@ -51,7 +51,7 @@ napi_value ResultSetProxy::NewInstance(napi_env env, std::shared_ptrGetBlock() != nullptr) { + if (resultSet != nullptr && resultSet->GetBlock() != nullptr) { proxy->sharedBlockName_ = resultSet->GetBlock()->Name(); proxy->sharedBlockAshmemFd_ = resultSet->GetBlock()->GetFd(); } @@ -201,7 +201,7 @@ napi_value ResultSetProxy::InitializeV9(napi_env env, napi_callback_info info) ResultSetProxy::~ResultSetProxy() { - LOG_INFO("ResultSetProxy destructor!"); + LOG_DEBUG("ResultSetProxy destructor!"); } ResultSetProxy::ResultSetProxy(std::shared_ptr resultSet) @@ -242,7 +242,8 @@ ResultSetProxy *ResultSetProxy::ParseInt32FieldByName( napi_get_cb_info(env, info, &argc, args, &self, nullptr); ResultSetProxy *resultSetProxy = nullptr; napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)); - RDB_CHECK_RETURN_NULLPTR(napi_get_value_int32(env, args[0], &field) == napi_ok); + RDB_CHECK_RETURN_NULLPTR(napi_get_value_int32(env, args[0], &field) == napi_ok, + "napi_get_value_int32 reurn invalid"); return resultSetProxy; } @@ -253,7 +254,8 @@ ResultSetProxy *ResultSetProxy::ParseFieldByName(napi_env env, napi_callback_inf napi_value args[1] = { 0 }; napi_get_cb_info(env, info, &argc, args, &self, nullptr); ResultSetProxy *resultSetProxy = nullptr; - RDB_CHECK_RETURN_NULLPTR(napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)) == napi_ok); + RDB_CHECK_RETURN_NULLPTR(napi_unwrap(env, self, reinterpret_cast(&resultSetProxy)) == napi_ok, + "napi_unwrap return invalid"); field = JSUtils::Convert2String(env, args[0]); return resultSetProxy; } @@ -273,8 +275,8 @@ napi_value ResultSetProxy::GoToRow(napi_env env, napi_callback_info info) { int32_t position; auto resultSetProxy = ParseInt32FieldByName(env, info, position, "position"); - RDB_NAPI_ASSERT_FROMV9( - env, resultSetProxy != nullptr, std::make_shared(), resultSetProxy->apiversion); + RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + std::make_shared(), resultSetProxy->apiversion); int errCode = resultSetProxy->resultSet_->GoToRow(position); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -295,7 +297,8 @@ napi_value ResultSetProxy::GetLong(napi_env env, napi_callback_info info) int32_t columnIndex; int64_t result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetLong(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -307,7 +310,8 @@ napi_value ResultSetProxy::GetColumnType(napi_env env, napi_callback_info info) int32_t columnIndex; ColumnType columnType; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetColumnType(columnIndex, columnType); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -318,8 +322,8 @@ napi_value ResultSetProxy::GoTo(napi_env env, napi_callback_info info) { int32_t offset; auto resultSetProxy = ParseInt32FieldByName(env, info, offset, "offset"); - RDB_NAPI_ASSERT_FROMV9( - env, resultSetProxy != nullptr, std::make_shared(), resultSetProxy->apiversion); + RDB_NAPI_ASSERT_FROMV9(env, resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + std::make_shared(), resultSetProxy->apiversion); int errCode = resultSetProxy->resultSet_->GoTo(offset); return JSUtils::Convert2JSValue(env, (errCode == E_OK)); } @@ -329,7 +333,8 @@ napi_value ResultSetProxy::GetColumnIndex(napi_env env, napi_callback_info info) std::string input; int32_t result = -1; auto resultSetProxy = ParseFieldByName(env, info, input); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetColumnIndex(input, result); if (errCode != E_OK) { LOG_ERROR("GetColumnIndex failed code:%{public}d, version:%{public}d", errCode, resultSetProxy->apiversion); @@ -342,7 +347,8 @@ napi_value ResultSetProxy::GetInt(napi_env env, napi_callback_info info) int32_t columnIndex; int32_t result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetInt(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -354,7 +360,8 @@ napi_value ResultSetProxy::GetColumnName(napi_env env, napi_callback_info info) int32_t columnIndex; std::string result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetColumnName(columnIndex, result); if (errCode != E_OK) { LOG_ERROR("GetColumnName failed code:%{public}d, version:%{public}d", errCode, resultSetProxy->apiversion); @@ -482,7 +489,8 @@ napi_value ResultSetProxy::GetBlob(napi_env env, napi_callback_info info) int32_t columnIndex; std::vector result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetBlob(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -495,7 +503,8 @@ napi_value ResultSetProxy::GetString(napi_env env, napi_callback_info info) int32_t columnIndex; std::string result; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetString(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -507,7 +516,8 @@ napi_value ResultSetProxy::GetDouble(napi_env env, napi_callback_info info) int32_t columnIndex; double result = 0.0; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->GetDouble(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -519,7 +529,8 @@ napi_value ResultSetProxy::IsColumnNull(napi_env env, napi_callback_info info) int32_t columnIndex; bool result = false; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); - RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr); + RDB_CHECK_RETURN_NULLPTR(resultSetProxy != nullptr && resultSetProxy->resultSet_ != nullptr, + "resultSetProxy or resultSet_ is nullptr"); int errCode = resultSetProxy->resultSet_->IsColumnNull(columnIndex, result); int version = resultSetProxy->apiversion; RDB_NAPI_ASSERT_FROMV9(env, errCode == E_OK, std::make_shared(), version); @@ -544,6 +555,8 @@ napi_value ResultSetProxy::GetSharedBlockName(napi_env env, napi_callback_info i ResultSetProxy *proxy; NAPI_CALL(env, napi_unwrap(env, thiz, reinterpret_cast(&proxy))); + RDB_CHECK_RETURN_NULLPTR(proxy != nullptr, + "ResultSetProxy::GetSharedBlockName proxy is nullptr"); return JSUtils::Convert2JSValue(env, proxy->sharedBlockName_); } @@ -555,6 +568,8 @@ napi_value ResultSetProxy::GetSharedBlockAshmemFd(napi_env env, napi_callback_in ResultSetProxy *proxy; NAPI_CALL(env, napi_unwrap(env, thiz, reinterpret_cast(&proxy))); + RDB_CHECK_RETURN_NULLPTR(proxy != nullptr, + "ResultSetProxy::GetSharedBlockAshmemFd proxy is nullptr"); return JSUtils::Convert2JSValue(env, proxy->sharedBlockAshmemFd_); } @@ -562,20 +577,18 @@ napi_value ResultSetProxy::GetSharedBlockAshmemFd(napi_env env, napi_callback_in } // namespace OHOS #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) -EXTERN_C_START -__attribute__((visibility("default"))) napi_value NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_NewInstance( - napi_env env, OHOS::NativeRdb::AbsSharedResultSet *resultSet) + +__attribute__((visibility("default"))) napi_value NewCInstance(napi_env env, + napi_value arg) asm("NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_NewInstance"); +napi_value NewCInstance(napi_env env, std::shared_ptr resultSet) { - return OHOS::RdbJsKit::ResultSetProxy::NewInstance( - env, std::shared_ptr(resultSet)); + return OHOS::RdbJsKit::ResultSetProxy::NewInstance(env, resultSet); } -__attribute__((visibility("default"))) OHOS::NativeRdb::AbsSharedResultSet * -NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_GetNativeObject(const napi_env &env, const napi_value &arg) +__attribute__((visibility("default"))) std::shared_ptr GetCObject(napi_env env, + napi_value arg) asm("NAPI_OHOS_Data_RdbJsKit_ResultSetProxy_GetNativeObject"); +std::shared_ptr GetCObject(napi_env env, napi_value arg) { - // the resultSet maybe release. - auto resultSet = OHOS::RdbJsKit::ResultSetProxy::GetNativeObject(env, arg); - return resultSet.get(); + return OHOS::RdbJsKit::ResultSetProxy::GetNativeObject(env, arg); } -EXTERN_C_END #endif \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h index 8777074e..1f1a6b70 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_error.h @@ -32,6 +32,8 @@ constexpr int E_NON_SYSTEM_APP_ERROR = 202; constexpr int E_INNER_ERROR = 14800000; constexpr int E_RESULT_GOTO_ERROR = 14800012; constexpr int E_RESULT_GET_ERROR = 14800013; +constexpr int E_NOT_STAGE_MODE = 14801001; +constexpr int E_DATA_GROUP_ID_INVALID = 14801002; const static std::map ERROR_MAPS = { { NativeRdb::E_WAL_SIZE_OVER_LIMIT, "The WAL file size over default limit." }, @@ -40,6 +42,10 @@ const static std::map ERROR_MAPS = { { NativeRdb::E_NOT_SUPPORTED, "Capability not supported" }, { E_RESULT_GOTO_ERROR, "The result set is empty or the specified location is invalid." }, { NativeRdb::E_INVALID_STATEMENT, "The column value is null or the column type is incompatible." }, + { E_NOT_STAGE_MODE, "Only supported in stage mode." }, + { E_DATA_GROUP_ID_INVALID, "The data group id is invalid." }, + { NativeRdb::E_GET_DATAOBSMGRCLIENT_FAIL, "Failed to get DataObsMgrClient." }, + { NativeRdb::E_TYPE_MISMATCH, "The type of the distributed table does not match"}, }; #define RDB_REVT_NOTHING @@ -79,6 +85,9 @@ const static std::map ERROR_MAPS = { #define CHECK_RETURN_NULL(assertion) \ CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, nullptr) +#define CHECK_RETURN_ERR(assertion) \ + CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, ERR) + #define CHECK_RETURN(assertion) \ CHECK_RETURN_CORE(assertion, RDB_REVT_NOTHING, RDB_REVT_NOTHING) diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_predicates.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_predicates.h index 7a30d69b..2a7aaa42 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_predicates.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_predicates.h @@ -96,6 +96,8 @@ private: static napi_value GetJoinConditions(napi_env env, napi_callback_info info); static napi_value InnerJoin(napi_env env, napi_callback_info info); static napi_value On(napi_env env, napi_callback_info info); + static napi_value GetStatement(napi_env env, napi_callback_info info); + static napi_value GetBindArgs(napi_env env, napi_callback_info info); static napi_value InDevices(napi_env env, napi_callback_info info); static napi_value InAllDevices(napi_env env, napi_callback_info info); diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h index 7a02f052..b9b8408d 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h @@ -74,25 +74,27 @@ private: static napi_value GetModifyTime(napi_env env, napi_callback_info info); static napi_value OnEvent(napi_env env, napi_callback_info info); static napi_value OffEvent(napi_env env, napi_callback_info info); + static napi_value Notify(napi_env env, napi_callback_info info); static constexpr int MIN_ON_EVENT_ARG_NUM = 2; static constexpr int MAX_ON_EVENT_ARG_NUM = 5; - class NapiCoudSyncCallback : public NapiUvQueue { - public: - explicit NapiCoudSyncCallback(napi_env env, napi_value callback) : NapiUvQueue(env, callback) {} - virtual ~NapiCoudSyncCallback() = default; + napi_value OnRemote(napi_env env, size_t argc, napi_value *argv); + napi_value OnLocal(napi_env env, const DistributedRdb::SubscribeOption &option, napi_value callback); + napi_value RegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, + std::map>> &observers, napi_value callback); - void OnSyncCompelete(const DistributedRdb::Details &details); - }; - - napi_value OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv); - napi_value OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv); + napi_value OffRemote(napi_env env, size_t argc, napi_value *argv); + napi_value OffLocal(napi_env env, const DistributedRdb::SubscribeOption &option, napi_value callback); + napi_value UnRegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, + std::map>> &observers, napi_value callback); std::mutex mutex_; bool isSystemAppCalled_ = false; std::shared_ptr queue_; std::list> observers_[DistributedRdb::SUBSCRIBE_MODE_MAX]; + std::map>> localObservers_; + std::map>> localSharedObservers_; }; } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h index 0d193e25..95208511 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h @@ -38,6 +38,8 @@ public: void OnChange(const Origin &origin, const PrimaryFields &fields, ChangeInfo &&changeInfo) override; + void OnChange() override; + private: int32_t mode_ = DistributedRdb::REMOTE; }; diff --git a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h index b9040a46..0b7878ff 100644 --- a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h +++ b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_predicates.h @@ -96,6 +96,8 @@ private: static napi_value GetJoinConditions(napi_env env, napi_callback_info info); static napi_value InnerJoin(napi_env env, napi_callback_info info); static napi_value On(napi_env env, napi_callback_info info); + static napi_value GetStatement(napi_env env, napi_callback_info info); + static napi_value GetBindArgs(napi_env env, napi_callback_info info); std::shared_ptr predicates_; }; diff --git a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h index 1f56f5cc..71aae8c5 100644 --- a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h @@ -19,6 +19,7 @@ #include #include +#include "js_uv_queue.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -66,6 +67,7 @@ private: std::mutex mutex_; bool isSystemAppCalled_ = false; + std::shared_ptr queue_; }; } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp index 5091991e..a40206bc 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp @@ -99,6 +99,22 @@ static napi_value ExportProgress(napi_env env) return progress; } +static napi_value ExportProgressCode(napi_env env) +{ + napi_value progressCode = nullptr; + napi_create_object(env, &progressCode); + + SET_NAPI_PROPERTY(progressCode, "SUCCESS", 0); + SET_NAPI_PROPERTY(progressCode, "UNKNOWN_ERROR", 1); + SET_NAPI_PROPERTY(progressCode, "NETWORK_ERROR", 2); + SET_NAPI_PROPERTY(progressCode, "CLOUD_DISABLED", 3); + SET_NAPI_PROPERTY(progressCode, "LOCKED_BY_OTHERS", 4); + SET_NAPI_PROPERTY(progressCode, "RECORD_LIMIT_EXCEEDED", 5); + SET_NAPI_PROPERTY(progressCode, "NO_SPACE_FOR_ASSET", 6); + napi_object_freeze(env, progressCode); + return progressCode; +} + static napi_value ExportDistributedType(napi_env env) { napi_value distributedType = nullptr; @@ -162,6 +178,7 @@ napi_status InitConstProperties(napi_env env, napi_value exports) DECLARE_NAPI_PROPERTY("SecurityLevel", ExportSecurityLevel(env)), #endif DECLARE_NAPI_PROPERTY("Progress", ExportProgress(env)), + DECLARE_NAPI_PROPERTY("ProgressCode", ExportProgressCode(env)), DECLARE_NAPI_PROPERTY("DistributedType", ExportDistributedType(env)), DECLARE_NAPI_PROPERTY("AssetStatus", ExportAssetStatus(env)), DECLARE_NAPI_PROPERTY("ChangeType", ExportChangeType(env)), diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp index 56e9cf5e..4e26ffb2 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp @@ -83,12 +83,10 @@ napi_value Convert2JSValue(napi_env env, const Asset &value) NAPI_CALL_RETURN_ERR(napi_create_object(env, &object), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, name), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, uri), object); - NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, id), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, createTime), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, modifyTime), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, size), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, path), object); - NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, hash), object); NAPI_CALL_RETURN_ERR(ADD_JS_PROPERTY(env, object, value, status), object); return object; } @@ -121,8 +119,9 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statis napi_set_named_property(env, jsValue, "total", total); napi_set_named_property(env, jsValue, "success", success); + napi_set_named_property(env, jsValue, "successful", success); napi_set_named_property(env, jsValue, "failed", failed); - napi_set_named_property(env, jsValue, "untreated", untreated); + napi_set_named_property(env, jsValue, "remained", untreated); return jsValue; } diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp index e8ae2aef..ffe6f710 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp @@ -70,6 +70,8 @@ void RdbPredicatesProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_GETTER_SETTER("joinConditions", GetJoinConditions, SetJoinConditions), DECLARE_NAPI_GETTER_SETTER("joinNames", GetJoinTableNames, SetJoinTableNames), DECLARE_NAPI_GETTER_SETTER("joinTypes", GetJoinTypes, SetJoinTypes), + DECLARE_NAPI_GETTER("statement", GetStatement), + DECLARE_NAPI_GETTER("bindArgs", GetBindArgs), #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) DECLARE_NAPI_FUNCTION("inDevices", InDevices), DECLARE_NAPI_FUNCTION("inAllDevices", InAllDevices), @@ -563,10 +565,28 @@ napi_value RdbPredicatesProxy::Limit(napi_env env, napi_callback_info info) { LOG_DEBUG("RdbPredicatesProxy::Limit begin."); napi_value thiz = nullptr; - int32_t limit = 0; - auto predicatesProxy = ParseInt32FieldByName(env, info, thiz, limit, "value"); + size_t argc = 2; + napi_value args[2] = { 0 }; + napi_get_cb_info(env, info, &argc, args, &thiz, nullptr); + RdbPredicatesProxy *predicatesProxy = GetNativePredicates(env, info); CHECK_RETURN_NULL(predicatesProxy && predicatesProxy->predicates_); - predicatesProxy->predicates_->Limit(limit); + RDB_NAPI_ASSERT(env, argc == 1 || argc == 2, std::make_shared("1 or 2")); + + int32_t offset = 0; + int32_t limit = 0; + if (argc == 1) { + napi_status status = napi_get_value_int32(env, args[0], &limit); + RDB_NAPI_ASSERT(env, status == napi_ok, std::make_shared("limit", "a number.")); + predicatesProxy->predicates_->Limit(limit); + } else { + napi_status status = napi_get_value_int32(env, args[0], &offset); + RDB_NAPI_ASSERT(env, status == napi_ok, std::make_shared("offset", "a number.")); + + status = napi_get_value_int32(env, args[1], &limit); + RDB_NAPI_ASSERT(env, status == napi_ok, std::make_shared("limit", "a number.")); + predicatesProxy->predicates_->Limit(offset, limit); + } + return thiz; } @@ -671,6 +691,28 @@ napi_value RdbPredicatesProxy::On(napi_env env, napi_callback_info info) return thiz; } +napi_value RdbPredicatesProxy::GetStatement(napi_env env, napi_callback_info info) +{ + napi_value thiz = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); + RdbPredicatesProxy *predicatesProxy = GetNativePredicates(env, info); + CHECK_RETURN_NULL(predicatesProxy && predicatesProxy->predicates_); + + std::string statement = predicatesProxy->predicates_->GetStatement(); + return JSUtils::Convert2JSValue(env, statement); +} + +napi_value RdbPredicatesProxy::GetBindArgs(napi_env env, napi_callback_info info) +{ + napi_value thiz = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr); + RdbPredicatesProxy *predicatesProxy = GetNativePredicates(env, info); + CHECK_RETURN_NULL(predicatesProxy && predicatesProxy->predicates_); + + std::vector bindArgs = predicatesProxy->predicates_->GetBindArgs(); + return JSUtils::Convert2JSValue(env, bindArgs); +} + napi_value RdbPredicatesProxy::Clear(napi_env env, napi_callback_info info) { LOG_DEBUG("RdbPredicatesProxy::Clear begin."); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp index b304a6b5..d0006a3f 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "js_utils.h" #include "logger.h" @@ -27,7 +28,6 @@ #include "napi_rdb_trace.h" #include "napi_result_set.h" #include "rdb_errno.h" -#include "rdb_types.h" #include "securec.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -153,7 +153,6 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_GETTER("isInTransaction", IsInTransaction), DECLARE_NAPI_GETTER("isOpen", IsOpen), DECLARE_NAPI_GETTER("path", GetPath), - DECLARE_NAPI_GETTER("isHoldingConnection", IsHoldingConnection), DECLARE_NAPI_GETTER("isReadOnly", IsReadOnly), DECLARE_NAPI_GETTER("isMemoryRdb", IsMemoryRdb), #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -164,6 +163,7 @@ void RdbStoreProxy::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("getModifyTime", GetModifyTime), DECLARE_NAPI_FUNCTION("on", OnEvent), DECLARE_NAPI_FUNCTION("off", OffEvent), + DECLARE_NAPI_FUNCTION("emit", Notify), #endif }; napi_value cons = nullptr; @@ -243,7 +243,6 @@ int ParserThis(const napi_env &env, const napi_value &self, std::shared_ptrrdbStore_, std::make_shared("RdbStore", "nullptr.")); context->boundObj = obj; - LOG_DEBUG("ParserThis RdbStoreProxy end"); return OK; } @@ -251,8 +250,6 @@ int ParseTableName(const napi_env &env, const napi_value &arg, std::shared_ptrtableName = JSUtils::Convert2String(env, arg); CHECK_RETURN_SET(!context->tableName.empty(), std::make_shared("table", "not empty")); - - LOG_DEBUG("ParseTableName end"); return OK; } @@ -274,8 +271,6 @@ int ParseDevice(const napi_env &env, const napi_value &arg, std::shared_ptrdevice = JSUtils::Convert2String(env, arg); CHECK_RETURN_SET(!context->device.empty(), std::make_shared("device", "not empty")); - - LOG_DEBUG("ParseDevice end"); return OK; } @@ -294,8 +289,6 @@ int ParseSyncModeArg(const napi_env &env, const napi_value &arg, std::shared_ptr CHECK_RETURN_SET(status == napi_ok, std::make_shared("mode", "a SyncMode Type.")); bool checked = context->enumArg == 0 || context->enumArg == 1; CHECK_RETURN_SET(checked, std::make_shared("mode", "a SyncMode of device.")); - - LOG_DEBUG("ParseSyncModeArg end"); return OK; } @@ -310,7 +303,6 @@ int ParseDistributedTypeArg(const napi_env &env, size_t argc, napi_value * argv, CHECK_RETURN_SET(JSUtils::IsNull(env, argv[1]) || checked, std::make_shared("distributedType", "a DistributedType")); } - LOG_DEBUG("ParseDistributedTypeArg end"); return OK; } @@ -323,7 +315,6 @@ int ParseDistributedConfigArg(const napi_env &env, size_t argc, napi_value * arg bool checked = status == napi_ok || JSUtils::IsNull(env, argv[2]); CHECK_RETURN_SET(checked, std::make_shared("distributedConfig", "a DistributedConfig type")); } - LOG_DEBUG("ParseDistributedConfigArg end"); return OK; } @@ -333,7 +324,16 @@ int ParseCloudSyncModeArg(const napi_env &env, const napi_value &arg, std::share bool checked = (status == napi_ok && context->syncMode >= DistributedRdb::TIME_FIRST && context->syncMode <= DistributedRdb::CLOUD_FIRST); CHECK_RETURN_SET(checked, std::make_shared("mode", "a SyncMode of cloud.")); - LOG_DEBUG("ParseCloudSyncModeArg end"); + return OK; +} + +int ParseCallback(const napi_env &env, const napi_value &arg, std::shared_ptr context) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, arg, &valueType); + CHECK_RETURN_SET((status == napi_ok && valueType == napi_function), + std::make_shared("callback", "a function.")); + NAPI_CALL_BASE(env, napi_create_reference(env, arg, 1, &context->callback_), ERR); return OK; } @@ -343,8 +343,6 @@ int ParseCloudSyncCallback(const napi_env &env, const napi_value &arg, std::shar napi_typeof(env, arg, &valueType); CHECK_RETURN_SET(valueType == napi_function, std::make_shared("a callback type")); napi_create_reference(env, arg, 1, &context->asyncHolder); - - LOG_DEBUG("ParseCloudSyncCallback end"); return OK; } @@ -371,7 +369,6 @@ int ParseDataSharePredicates(const napi_env &env, const napi_value &arg, std::sh std::shared_ptr dsPredicates = proxy->predicates_; RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(*dsPredicates, context->tableName); context->rdbPredicates = std::make_shared(rdbPredicates); - LOG_DEBUG("Parse DSPredicates end"); #endif return OK; } @@ -379,7 +376,6 @@ int ParseDataSharePredicates(const napi_env &env, const napi_value &arg, std::sh int ParseNewKey(const napi_env &env, const napi_value &arg, std::shared_ptr context) { context->newKey = JSUtils::Convert2U8Vector(env, arg); - LOG_DEBUG("ParseNewKey end"); return OK; } @@ -400,8 +396,6 @@ int ParseAlias(const napi_env &env, const napi_value &arg, std::shared_ptraliasName = JSUtils::Convert2String(env, arg); CHECK_RETURN_SET(!context->aliasName.empty(), std::make_shared("aliasName", "not empty")); - - LOG_DEBUG("ParseAlias end"); return OK; } @@ -409,15 +403,12 @@ int ParsePath(const napi_env &env, const napi_value &arg, std::shared_ptrpathName = JSUtils::Convert2String(env, arg); CHECK_RETURN_SET(!context->pathName.empty(), std::make_shared("pathName", "not empty")); - - LOG_DEBUG("ParsePath end"); return OK; } int ParseSelectionArgs(const napi_env &env, const napi_value &arg, std::shared_ptr context) { context->selectionArgs = JSUtils::Convert2StrVector(env, arg); - LOG_DEBUG("ParseSelectionArgs end"); return OK; } @@ -425,8 +416,6 @@ int ParseSql(const napi_env &env, const napi_value &arg, std::shared_ptrsql = JSUtils::Convert2String(env, arg, false); CHECK_RETURN_SET(!context->sql.empty(), std::make_shared("sql", "not empty")); - - LOG_DEBUG("ParseSql end"); return OK; } @@ -453,7 +442,6 @@ int ParseValuesBucket(const napi_env &env, const napi_value &arg, std::shared_pt LOG_WARN("bad value type of key %{public}s", keyStr.c_str()); } } - LOG_DEBUG("ParseValuesBucket end"); return OK; } @@ -488,14 +476,11 @@ int ParseConflictResolution(const napi_env &env, const napi_value &arg, std::sha bool checked = (conflictResolution >= min) && (conflictResolution <= max); CHECK_RETURN_SET(checked, std::make_shared("conflictResolution", "a ConflictResolution.")); context->conflictResolution = static_cast(conflictResolution); - LOG_DEBUG("ParseConflictResolution end"); return OK; } napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RdbStoreProxy::Insert start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 2 || argc == 3, std::make_shared("2 to 4")); @@ -508,24 +493,22 @@ napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) }; auto exec = [context]() -> int { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->InsertWithConflictResolution(context->int64Output, context->tableName, context->valuesBucket, context->conflictResolution); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->int64Output, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Insert end"); }; context->SetAction(env, info, input, exec, output); - CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + CHECK_RETURN_NULL(!(context->error) || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RdbStoreProxy::BatchInsert start."); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 2, std::make_shared("2 or 3")); @@ -534,14 +517,13 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseValuesBuckets(env, argv[1], context)); }; auto exec = [context]() -> int { - LOG_INFO("RdbStoreProxy::BatchInsert Async."); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->BatchInsert(context->int64Output, context->tableName, context->valuesBuckets); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->int64Output, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::BatchInsert end."); }; context->SetAction(env, info, input, exec, output); @@ -551,7 +533,6 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) { - LOG_DEBUG("RdbStoreProxy::Delete start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 1 || argc == 2, std::make_shared("1 to 3")); @@ -564,14 +545,14 @@ napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) } }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Delete Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->rdbPredicates != nullptr); return obj->rdbStore_->Delete(context->intOutput, *(context->rdbPredicates)); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->intOutput, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Delete end"); }; context->SetAction(env, info, input, exec, output); @@ -581,8 +562,6 @@ napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RdbStoreProxy::Update start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN(OK == ParserThis(env, self, context)); @@ -604,8 +583,9 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) } }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Update Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->rdbPredicates != nullptr); return obj->rdbStore_->UpdateWithConflictResolution(context->intOutput, context->tableName, context->valuesBucket, context->rdbPredicates->GetWhereClause(), context->rdbPredicates->GetWhereArgs(), context->conflictResolution); @@ -613,7 +593,6 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->intOutput, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Update end"); }; context->SetAction(env, info, input, exec, output); @@ -623,7 +602,6 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN(OK == ParserThis(env, self, context)); @@ -644,8 +622,9 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) }; auto exec = [context]() -> int { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->rdbPredicates != nullptr); context->resultSet_value = obj->rdbStore_->Query(*(context->rdbPredicates), context->columns); - LOG_DEBUG("RdbStoreProxy::Query result is nullptr ? %{public}d", (context->resultSet_value == nullptr)); return (context->resultSet_value != nullptr) ? E_OK : E_ERROR; }; auto output = [context](napi_env env, napi_value &result) { @@ -661,7 +640,6 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) napi_value RdbStoreProxy::RemoteQuery(napi_env env, napi_callback_info info) { - LOG_DEBUG("RdbStoreProxy::RemoteQuery start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 3 || argc == 4, std::make_shared("3 to 5")); @@ -674,18 +652,17 @@ napi_value RdbStoreProxy::RemoteQuery(napi_env env, napi_callback_info info) } }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::RemoteQuery Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int errCode = E_ERROR; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->rdbPredicates != nullptr); context->newResultSet = obj->rdbStore_->RemoteQuery(context->device, *(context->rdbPredicates), context->columns, errCode); - LOG_DEBUG("RemoteQuerry ret is %{public}d.", errCode); return errCode; }; auto output = [context](napi_env env, napi_value &result) { result = ResultSetProxy::NewInstance(env, context->newResultSet); CHECK_RETURN_SET_E(result != nullptr, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::RemoteQuery end"); }; context->SetAction(env, info, input, exec, output); @@ -713,6 +690,7 @@ napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) auto exec = [context]() -> int { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->resultSet_value = obj->rdbStore_->QueryByStep(context->sql, context->columns); LOG_ERROR("RdbStoreProxy::QuerySql is nullptr ? %{public}d ", context->resultSet_value == nullptr); #endif @@ -766,7 +744,6 @@ int ParseBindArgs(const napi_env &env, const napi_value &arg, std::shared_ptr(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 1 || argc == 2, std::make_shared("1 to 3")); @@ -777,14 +754,13 @@ napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) } }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::ExecuteSql Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->ExecuteSql(context->sql, context->bindArgs); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::ExecuteSql end"); }; context->SetAction(env, info, input, exec, output); @@ -794,7 +770,6 @@ napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) { - LOG_DEBUG("RdbStoreProxy::Count start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 1, std::make_shared("1 or 2")); @@ -802,14 +777,14 @@ napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParsePredicates(env, argv[0], context)); }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Count Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); + CHECK_RETURN_ERR(context->predicatesProxy != nullptr && context->predicatesProxy->GetPredicates() != nullptr); return obj->rdbStore_->Count(context->int64Output, *(context->predicatesProxy->GetPredicates())); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->int64Output, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Count end"); }; context->SetAction(env, info, input, exec, output); @@ -819,8 +794,6 @@ napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RdbStoreProxy::Replace start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 2, std::make_shared("2 or 3")); @@ -829,14 +802,13 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseValuesBucket(env, argv[1], context)); }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Replace Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->Replace(context->int64Output, context->tableName, context->valuesBucket); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, context->int64Output, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Replace end"); }; context->SetAction(env, info, input, exec, output); @@ -846,7 +818,6 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) { - LOG_DEBUG("RdbStoreProxy::Backup start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 1, std::make_shared("1 or 2")); @@ -854,14 +825,13 @@ napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseTableName(env, argv[0], context)); }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Backup Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->Backup(context->tableName, context->newKey); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Backup end"); }; context->SetAction(env, info, input, exec, output); @@ -871,7 +841,6 @@ napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) { - LOG_DEBUG("RdbStoreProxy::Attach start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 3, std::make_shared("3 or 4")); @@ -881,14 +850,13 @@ napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseNewKey(env, argv[2], context)); }; auto exec = [context]() -> int { - LOG_DEBUG("RdbStoreProxy::Attach Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->Attach(context->aliasName, context->pathName, context->newKey); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RdbStoreProxy::Attach end"); }; context->SetAction(env, info, input, exec, output); @@ -896,17 +864,6 @@ napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -napi_value RdbStoreProxy::IsHoldingConnection(napi_env env, napi_callback_info info) -{ - napi_value thisObj = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr); - RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); - RDB_NAPI_ASSERT(env, rdbStoreProxy && rdbStoreProxy->rdbStore_, std::make_shared("RdbStore", "valid")); - bool out = rdbStoreProxy->rdbStore_->IsHoldingConnection(); - LOG_DEBUG("RdbStoreProxy::IsHoldingConnection out is : %{public}d", out); - return JSUtils::Convert2JSValue(env, out); -} - napi_value RdbStoreProxy::IsReadOnly(napi_env env, napi_callback_info info) { napi_value thisObj = nullptr; @@ -992,6 +949,7 @@ napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info) auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::QueryByStep Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->resultSet_value = obj->rdbStore_->QueryByStep(context->sql, context->columns); LOG_ERROR("RdbStoreProxy::QueryByStep is nullptr ? %{public}d ", context->resultSet_value == nullptr); return (context->resultSet_value != nullptr) ? E_OK : E_ERROR; @@ -1069,6 +1027,7 @@ napi_value RdbStoreProxy::Restore(napi_env env, napi_callback_info info) auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::Restore Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->Restore(context->srcName, context->newKey); }; auto output = [context](napi_env env, napi_value &result) { @@ -1097,6 +1056,7 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->SetDistributedTables( context->tablesNames, context->distributedType, context->distributedConfig); }; @@ -1125,6 +1085,7 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); int errCode = E_ERROR; + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->tableName = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName, errCode); return errCode; }; @@ -1156,6 +1117,8 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) SyncOption option; option.mode = static_cast(context->enumArg); option.isBlock = true; + CHECK_RETURN_ERR(context->predicatesProxy != nullptr && context->predicatesProxy->GetPredicates() != nullptr); + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); return obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(), [context](const SyncResult &result) { context->syncResult = result; }); }; @@ -1188,12 +1151,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseCloudSyncCallback(env, argv[index++], context)); CHECK_RETURN_SET_E(index == argc - 1 || index == argc, std::make_shared("2 - 4")); if (index == argc - 1) { - napi_valuetype valueType = napi_undefined; - napi_typeof(env, argv[index], &valueType); - if (valueType == napi_function) { - LOG_INFO("asyncCall set callback"); - NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, argv[index], 1, &context->callback_)); - } + CHECK_RETURN(OK == ParseCallback(env, argv[index], context)); } }; auto exec = [context]() -> int { @@ -1202,7 +1160,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) SyncOption option; option.mode = static_cast(context->syncMode); option.isBlock = false; - + CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr); context->execCode_ = obj->rdbStore_->Sync(option, context->tablesNames, [queue = obj->queue_, callback = context->asyncHolder](const Details &details) { if (queue == nullptr || callback == nullptr) { @@ -1216,7 +1174,6 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) }); return OK; }; - auto output = [context](napi_env env, napi_value &result) { LOG_DEBUG("RdbStoreProxy::CloudSync output"); if (context->execCode_ != E_OK && context->asyncHolder != nullptr) { @@ -1225,9 +1182,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) napi_status status = napi_get_undefined(env, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); }; - context->SetAll(env, info, input, exec, output); - CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); } @@ -1260,12 +1215,9 @@ napi_value RdbStoreProxy::GetModifyTime(napi_env env, napi_callback_info info) return AsyncCall::Call(env, context); } -napi_value RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv) +napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) { napi_valuetype type; - napi_typeof(env, argv[0], &type); - RDB_NAPI_ASSERT(env, type == napi_number, std::make_shared("type", "SubscribeType")); - int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX; napi_get_value_int32(env, argv[0], &mode); bool valid = (mode >= 0 && mode < SubscribeMode::SUBSCRIBE_MODE_MAX); @@ -1279,20 +1231,50 @@ napi_value RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_valu return *observer == argv[1]; }); if (result) { - LOG_INFO("RdbStoreProxy::OnDataChangeEvent: duplicate subscribe"); + LOG_INFO("duplicate subscribe"); return nullptr; } SubscribeOption option; option.mode = static_cast(mode); auto observer = std::make_shared(env, argv[1], mode); int errCode = rdbStore_->Subscribe(option, observer.get()); - RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(E_ERROR)); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); observers_[mode].push_back(observer); - LOG_INFO("RdbStoreProxy::OnDataChangeEvent: subscribe success"); + LOG_INFO("subscribe success"); return nullptr; } -napi_value RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv) +napi_value RdbStoreProxy::RegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, + std::map>> &observers, napi_value callback) +{ + std::lock_guard lockGuard(mutex_); + observers.try_emplace(option.event); + auto &list = observers.find(option.event)->second; + bool result = std::any_of(list.begin(), list.end(), [callback](const auto &observer) { + return *observer == callback; + }); + if (result) { + LOG_INFO("duplicate subscribe event: %{public}s", option.event.c_str()); + return nullptr; + } + + auto localObserver = std::make_shared(env, callback); + int errCode = rdbStore_->Subscribe(option, localObserver.get()); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + observers[option.event].push_back(localObserver); + LOG_INFO("subscribe success event: %{public}s", option.event.c_str()); + return nullptr; +} + +napi_value RdbStoreProxy::OnLocal(napi_env env, const DistributedRdb::SubscribeOption &option, napi_value callback) +{ + if (option.mode == SubscribeMode::LOCAL) { + return RegisteredObserver(env, option, localObservers_, callback); + } + return RegisteredObserver(env, option, localSharedObservers_, callback); +} + +napi_value RdbStoreProxy::OffRemote(napi_env env, size_t argc, napi_value *argv) { napi_valuetype type; napi_typeof(env, argv[0], &type); @@ -1310,32 +1292,95 @@ napi_value RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_val option.mode = static_cast(mode); std::lock_guard lockGuard(mutex_); for (auto it = observers_[mode].begin(); it != observers_[mode].end(); it++) { - if (**it == argv[1]) { + if (*it != nullptr && **it == argv[1]) { int errCode = rdbStore_->UnSubscribe(option, it->get()); - RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(E_ERROR)); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); observers_[mode].erase(it); - LOG_INFO("RdbStoreProxy::OffDataChangeEvent: observer unsubscribe success"); - return nullptr ; + LOG_INFO("observer unsubscribe success"); + return nullptr; + } + } + LOG_INFO("observer not found"); + return nullptr; +} + +napi_value RdbStoreProxy::UnRegisteredObserver(napi_env env, const DistributedRdb::SubscribeOption &option, + std::map>> &observers, napi_value callback) +{ + std::lock_guard lockGuard(mutex_); + auto obs = observers.find(option.event); + if (obs == observers.end()) { + LOG_INFO("observer not found, event: %{public}s", option.event.c_str()); + return nullptr; + } + + if (callback) { + auto &list = obs->second; + for (auto it = list.begin(); it != list.end(); it++) { + if (**it == callback) { + int errCode = rdbStore_->UnSubscribe(option, it->get()); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + list.erase(it); + break; + } } + if (list.empty()) { + observers.erase(option.event); + } + } else { + int errCode = rdbStore_->UnSubscribe(option, nullptr); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + observers.erase(option.event); } - LOG_INFO("RdbStoreProxy::OffDataChangeEvent: observer not found"); + LOG_INFO("unsubscribe success, event: %{public}s", option.event.c_str()); return nullptr; } +napi_value RdbStoreProxy::OffLocal(napi_env env, const DistributedRdb::SubscribeOption &option, napi_value callback) +{ + if (option.mode == SubscribeMode::LOCAL) { + return UnRegisteredObserver(env, option, localObservers_, callback); + } + return UnRegisteredObserver(env, option, localSharedObservers_, callback); +} + napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) { size_t argc = 3; napi_value argv[3]{}; napi_value self = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); - RDB_NAPI_ASSERT(env, status == napi_ok && argc == 3, std::make_shared("3")); + // 'argc == 3' represents the number of parameters is three + RDB_NAPI_ASSERT(env, status == napi_ok && (argc == 3), std::make_shared("3")); auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); - std::string event = JSUtils::Convert2String(env, argv[0]); - if (event == "dataChange") { - return proxy->OnDataChangeEvent(env, argc - 1, argv + 1); + napi_valuetype type; + napi_typeof(env, argv[1], &type); + if (type == napi_number) { + std::string event = JSUtils::Convert2String(env, argv[0]); + RDB_NAPI_ASSERT(env, event == "dataChange", std::make_shared("event", "dataChange")); + return proxy->OnRemote(env, argc - 1, argv + 1); + } else if (type == napi_boolean) { + bool valueBool = false; + napi_get_value_bool(env, argv[1], &valueBool); + + napi_typeof(env, argv[0], &type); + RDB_NAPI_ASSERT(env, type == napi_string, std::make_shared("event", "string")); + std::string event = JSUtils::Convert2String(env, argv[0], false); + RDB_NAPI_ASSERT(env, !event.empty(), std::make_shared("event", "a not empty string.")); + // 'argv[2]' represents a callback function + napi_typeof(env, argv[2], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); + SubscribeOption option; + option.event = event; + valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; + // 'argv[2]' represents a callback function + return proxy->OnLocal(env, option, argv[2]); + } else { + RDB_NAPI_ASSERT(env, false, + std::make_shared("type or supportShared ", "SubscribeType or bool")); } return nullptr; } @@ -1343,28 +1388,60 @@ napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) { size_t argc = 3; - napi_value argv[3]{}; + // 'argv[3]' represents an array containing three elements + napi_value argv[3] = { nullptr }; napi_value self = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); - RDB_NAPI_ASSERT(env, status == napi_ok && argc == 3, std::make_shared("3")); + // 'argc == 2 || argc == 3' represents the number of parameters is two or three + RDB_NAPI_ASSERT(env, status == napi_ok && (argc == 2 || argc == 3), std::make_shared("2 or 3")); auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); - std::string event = JSUtils::Convert2String(env, argv[0]); - if (event == "dataChange") { - return proxy->OffDataChangeEvent(env, argc - 1, argv + 1); + napi_valuetype type; + napi_typeof(env, argv[1], &type); + if (type == napi_number) { + std::string event = JSUtils::Convert2String(env, argv[0]); + RDB_NAPI_ASSERT(env, event == "dataChange", std::make_shared("event", "dataChange")); + return proxy->OffRemote(env, argc - 1, argv + 1); + } else if (type == napi_boolean) { + bool valueBool = false; + napi_get_value_bool(env, argv[1], &valueBool); + + std::string event = JSUtils::Convert2String(env, argv[0], false); + RDB_NAPI_ASSERT(env, !event.empty(), std::make_shared("event", "a not empty string.")); + + // 'argc == 3' represents determine whether the value of variable 'argc' is equal to '3' + if (argc == 3) { + // 'argv[2]' represents a callback function + napi_typeof(env, argv[2], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("observer", "function")); + } + SubscribeOption option; + option.event = event; + valueBool ? option.mode = SubscribeMode::LOCAL_SHARED : option.mode = SubscribeMode::LOCAL; + // 'argv[2]' represents a callback function + return proxy->OffLocal(env, option, argv[2]); + } else { + RDB_NAPI_ASSERT(env, false, + std::make_shared("type or supportShared ", "SubscribeType or bool")); } return nullptr; } -void RdbStoreProxy::NapiCoudSyncCallback::OnSyncCompelete(const DistributedRdb::Details &details) +napi_value RdbStoreProxy::Notify(napi_env env, napi_callback_info info) { - LOG_DEBUG("NapiCoudSyncCallback::OnSyncCompelete begin"); - CallFunction([details](napi_env env, int &argc, napi_value *argv) { - argc = 1; - argv[0] = details.empty() ? nullptr : JSUtils::Convert2JSValue(env, details.begin()->second); - }); + size_t argc = 1; + napi_value argv[1]{}; + napi_value self = nullptr; + napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + RDB_NAPI_ASSERT(env, status == napi_ok && argc == 1, std::make_shared("1")); + auto *proxy = GetNativeInstance(env, self); + RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); + + int errCode = proxy->rdbStore_->Notify(JSUtils::Convert2String(env, argv[0])); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + return nullptr; } #endif } // namespace RelationalStoreJsKit diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp index e665fdcf..9e8b40a7 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp @@ -18,7 +18,6 @@ #include #include #include - #include "js_ability.h" #include "js_utils.h" #include "logger.h" @@ -52,28 +51,15 @@ struct HelperRdbContext : public Context { int ParseContext(const napi_env &env, const napi_value &object, std::shared_ptr context) { + napi_valuetype type; + napi_typeof(env, object, &type); + CHECK_RETURN_SET(type == napi_object, std::make_shared("context", "object.")); auto abilityContext = JSAbility::GetContext(env, object); CHECK_RETURN_SET(abilityContext != nullptr, std::make_shared("context", "a Context.")); context->abilitycontext = abilityContext; return OK; } -int ParseDatabaseName(const napi_env &env, const napi_value &object, std::shared_ptr context) -{ - napi_value value; - napi_get_named_property(env, object, "name", &value); - CHECK_RETURN_SET(value != nullptr, std::make_shared("config", "a StoreConfig.")); - - std::string name = JSUtils::Convert2String(env, value); - CHECK_RETURN_SET(!name.empty(), std::make_shared("config", "a StoreConfig.")); - if (name.find("/") != std::string::npos) { - CHECK_RETURN_SET(false, std::make_shared("StoreConfig.name", "a file name without path")); - } - - context->config.SetName(std::move(name)); - return OK; -} - int ParseIsEncrypt(const napi_env &env, const napi_value &object, std::shared_ptr context) { napi_value value = nullptr; @@ -88,10 +74,6 @@ int ParseIsEncrypt(const napi_env &env, const napi_value &object, std::shared_pt int ParseContextProperty(const napi_env &env, std::shared_ptr context) { - if (context->abilitycontext == nullptr) { - int status = ParseContext(env, nullptr, context); // when no context as arg got from application. - CHECK_RETURN_SET(status == OK, std::make_shared("context", "a Context.")); - } context->config.SetModuleName(context->abilitycontext->GetModuleName()); context->config.SetArea(context->abilitycontext->GetArea()); context->config.SetBundleName(context->abilitycontext->GetBundleName()); @@ -106,16 +88,27 @@ int ParseContextProperty(const napi_env &env, std::shared_ptr return OK; } -int ParseDatabaseDir(const napi_env &env, std::shared_ptr context) +int ParseDatabaseDir(const napi_env &env, const napi_value &object, std::shared_ptr context) { - if (context->abilitycontext == nullptr) { - int status = ParseContext(env, nullptr, context); // when no context as arg got from application. - CHECK_RETURN_SET(status == OK, std::make_shared("context", "a Context.")); - } - CHECK_RETURN_SET(context->abilitycontext != nullptr, std::make_shared("context", "a Context.")); int errorCode = E_OK; - std::string databaseName = context->config.GetName(); - std::string databaseDir = context->abilitycontext->GetDatabaseDir(); + napi_value value; + napi_get_named_property(env, object, "name", &value); + CHECK_RETURN_SET(value != nullptr, std::make_shared("config", "a StoreConfig.")); + std::string databaseName = JSUtils::Convert2String(env, value); + CHECK_RETURN_SET(!databaseName.empty(), std::make_shared("StoreConfig.name", "not empty.")); + if (databaseName.find("/") != std::string::npos) { + CHECK_RETURN_SET(false, std::make_shared("StoreConfig.name", "a file name without path")); + } + context->config.SetName(databaseName); + + std::string databaseDir; + if (context->config.GetDataGroupId().empty()) { + databaseDir = context->abilitycontext->GetDatabaseDir(); + } else { + errorCode = context->abilitycontext->GetSystemDatabaseDir(context->config.GetDataGroupId(), databaseDir); + CHECK_RETURN_SET((errorCode == E_OK), std::make_shared(E_DATA_GROUP_ID_INVALID)); + } + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("config", "a StoreConfig.")); context->config.SetPath(std::move(realPath)); @@ -146,13 +139,30 @@ int ParseSecurityLevel(const napi_env &env, const napi_value &object, std::share return OK; } +int ParseDataGroupId(const napi_env &env, const napi_value &object, std::shared_ptr context) +{ + bool hasProp = false; + napi_status status = napi_has_named_property(env, object, "dataGroupId", &hasProp); + if (status == napi_ok && hasProp) { + napi_value value = nullptr; + status = napi_get_named_property(env, object, "dataGroupId", &value); + CHECK_RETURN_SET(status == napi_ok, std::make_shared("config", "with dataGroupId.")); + std::string dataGroupId = JSUtils::Convert2String(env, value); + CHECK_RETURN_SET(!dataGroupId.empty(), std::make_shared + ("StoreConfig.dataGroupId", "not empty.")); + CHECK_RETURN_SET(context->abilitycontext->IsStageMode(), std::make_shared(E_NOT_STAGE_MODE)); + context->config.SetDataGroupId(JSUtils::Convert2String(env, value)); + } + return OK; +} + int ParseStoreConfig(const napi_env &env, const napi_value &object, std::shared_ptr context) { - CHECK_RETURN_CORE(OK == ParseDatabaseName(env, object, context), RDB_REVT_NOTHING, ERR); CHECK_RETURN_CORE(OK == ParseIsEncrypt(env, object, context), RDB_REVT_NOTHING, ERR); CHECK_RETURN_CORE(OK == ParseSecurityLevel(env, object, context), RDB_REVT_NOTHING, ERR); + CHECK_RETURN_CORE(OK == ParseDataGroupId(env, object, context), RDB_REVT_NOTHING, ERR); CHECK_RETURN_CORE(OK == ParseContextProperty(env, context), RDB_REVT_NOTHING, ERR); - CHECK_RETURN_CORE(OK == ParseDatabaseDir(env, context), RDB_REVT_NOTHING, ERR); + CHECK_RETURN_CORE(OK == ParseDatabaseDir(env, object, context), RDB_REVT_NOTHING, ERR); return OK; } @@ -164,6 +174,8 @@ int ParsePath(const napi_env &env, const napi_value &arg, std::shared_ptr("name", "a without path without /.")); + CHECK_RETURN_SET(context->abilitycontext != nullptr, + std::make_shared("abilitycontext", "abilitycontext is nullptr")); std::string databaseDir = context->abilitycontext->GetDatabaseDir(); int errorCode = E_OK; std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); @@ -173,6 +185,16 @@ int ParsePath(const napi_env &env, const napi_value &arg, std::shared_ptr= argc) { + return false; + } + napi_valuetype type; + NAPI_CALL_BASE(env, napi_typeof(env, argv[arg], &type), false); + return type == napi_string; +} + class DefaultOpenCallback : public RdbOpenCallback { public: int OnCreate(RdbStore &rdbStore) override @@ -187,18 +209,13 @@ public: napi_value GetRdbStore(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RelationalStoreJsKit::GetRdbStore start"); auto context = std::make_shared(); auto input = [context, info](napi_env env, size_t argc, napi_value *argv, napi_value self) { - bool checked = JSAbility::CheckContext(env, info); - CHECK_RETURN_SET_E(checked, std::make_shared("context", "a valid Context.")); CHECK_RETURN_SET_E(argc == 2, std::make_shared("2 or 3")); CHECK_RETURN(OK == ParseContext(env, argv[0], context)); CHECK_RETURN(OK == ParseStoreConfig(env, argv[1], context)); }; auto exec = [context]() -> int { - LOG_DEBUG("RelationalStoreJsKit::GetRdbStore Async"); int errCode = OK; DefaultOpenCallback callback; context->proxy = RdbHelper::GetRdbStore(context->config, -1, callback, errCode); @@ -207,7 +224,6 @@ napi_value GetRdbStore(napi_env env, napi_callback_info info) auto output = [context](napi_env env, napi_value &result) { result = RdbStoreProxy::NewInstance(env, context->proxy, context->isSystemAppCalled); CHECK_RETURN_SET_E(result != nullptr, std::make_shared(E_ERROR)); - LOG_DEBUG("RelationalStoreJsKit::GetRdbStore end"); }; context->SetAction(env, info, input, exec, output); @@ -217,13 +233,15 @@ napi_value GetRdbStore(napi_env env, napi_callback_info info) napi_value DeleteRdbStore(napi_env env, napi_callback_info info) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - LOG_DEBUG("RelationalStoreJsKit::DeleteRdbStore start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN_SET_E(argc == 2, std::make_shared("2 or 3")); CHECK_RETURN(OK == ParseContext(env, argv[0], context)); - CHECK_RETURN(OK == ParsePath(env, argv[1], context)); + if (IsNapiString(env, argc, argv, 1)) { + CHECK_RETURN(OK == ParsePath(env, argv[1], context)); + } else { + CHECK_RETURN(OK == ParseStoreConfig(env, argv[1], context)); + } }; auto exec = [context]() -> int { return RdbHelper::DeleteRdbStore(context->config.GetPath()); @@ -231,7 +249,6 @@ napi_value DeleteRdbStore(napi_env env, napi_callback_info info) auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_create_int64(env, OK, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); - LOG_DEBUG("RelationalStoreJsKit::DeleteRdbStore end"); }; context->SetAction(env, info, input, exec, output); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp index 562cf7d9..1daa2b88 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp @@ -59,6 +59,11 @@ void NapiRdbStoreObserver::OnChange(const Origin &origin, const PrimaryFields &f RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); } +void NapiRdbStoreObserver::OnChange() +{ + CallFunction([](napi_env env, int &argc, napi_value *argv) {}); +} + NapiRdbStoreObserver::JSChangeInfo::JSChangeInfo(const Origin &origin, ChangeInfo::iterator info) { table = info->first; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp index 05ba2c8e..909d2cb3 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp @@ -144,7 +144,7 @@ napi_value ResultSetProxy::Initialize(napi_env env, napi_callback_info info) ResultSetProxy::~ResultSetProxy() { - LOG_INFO("ResultSetProxy destructor!"); + LOG_DEBUG("ResultSetProxy destructor!"); } ResultSetProxy::ResultSetProxy(std::shared_ptr resultSet) diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp index 795c65ab..0c7c739a 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp @@ -55,6 +55,9 @@ void NapiUvQueue::CallFunction(NapiArgsGenerator genArgs) uv_queue_work(loop_, work, [](uv_work_t* work) {}, [](uv_work_t* work, int st) { auto queue = static_cast(work->data); napi_handle_scope scope = nullptr; + if (queue == nullptr) { + return; + } napi_open_handle_scope(queue->env_, &scope); if (scope == nullptr) { return; diff --git a/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp b/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp index 295c2c09..add783ff 100644 --- a/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp +++ b/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp @@ -16,7 +16,6 @@ #include "multi_platform_endian.h" #include -#if defined(WINDOWS_PLATFORM) namespace OHOS { uint16_t Endian::LeToH(uint16_t value) { @@ -36,4 +35,3 @@ uint32_t Endian::HToLe(uint32_t value) return htole32(value); } } -#endif diff --git a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp index 6d41306f..64a4b269 100644 --- a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp +++ b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp @@ -151,6 +151,10 @@ int SharedBlock::Clear() if (mReadOnly) { return SHARED_BLOCK_INVALID_OPERATION; } + if (mHeader == nullptr) { + LOG_ERROR("SharedBlock::Clear mHeader is nullptr"); + return SHARED_BLOCK_BAD_VALUE; + } mHeader->unusedOffset = sizeof(SharedBlockHeader) + sizeof(RowGroupHeader); mHeader->firstRowGroupOffset = sizeof(SharedBlockHeader); diff --git a/relational_store/frameworks/native/dataability/src/data_ability_predicates.cpp b/relational_store/frameworks/native/dataability/src/data_ability_predicates.cpp index 35cb6615..d11b766f 100644 --- a/relational_store/frameworks/native/dataability/src/data_ability_predicates.cpp +++ b/relational_store/frameworks/native/dataability/src/data_ability_predicates.cpp @@ -26,7 +26,7 @@ DataAbilityPredicates::DataAbilityPredicates() : isRawSelection(false), judgeSou { } -DataAbilityPredicates::DataAbilityPredicates(std::string rawSelection) : isRawSelection(true), judgeSource(false) +DataAbilityPredicates::DataAbilityPredicates(const std::string &rawSelection) : isRawSelection(true), judgeSource(false) { AbsPredicates::SetWhereClause(rawSelection); } diff --git a/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp b/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp index aa11c7b2..cf897546 100644 --- a/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp +++ b/relational_store/frameworks/native/dataability/src/ishared_result_set_proxy.cpp @@ -40,7 +40,7 @@ std::shared_ptr ISharedResultSetProxy::CreateProxy(MessagePa return nullptr; } sptr result = iface_cast(remoter); - if (result->sharedBlock_ == nullptr) { + if (result->GetBlock() == nullptr) { AppDataFwk::SharedBlock::ReadMessageParcel(parcel, result->sharedBlock_); } return std::shared_ptr(result.GetRefPtr(), [keep = result] (AbsSharedResultSet *) {}); diff --git a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h index 4d0af985..ef7d18cd 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h +++ b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h @@ -92,4 +92,4 @@ private: static inline BrokerDelegator delegator_; }; } // namespace OHOS::DistributedRdb -#endif +#endif \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h index 9513c388..1112a61e 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -23,15 +23,51 @@ #include #include +#include "dataobs_mgr_client.h" +#include "data_ability_observer_stub.h" #include "rdb_store.h" #include "rdb_store_config.h" +#include "refbase.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" namespace OHOS { class ExecutorPool; } + namespace OHOS::NativeRdb { +class RdbStoreLocalObserver { +public: + explicit RdbStoreLocalObserver(DistributedRdb::RdbStoreObserver *observer) : observer_(observer) {}; + virtual ~RdbStoreLocalObserver() {}; + void OnChange() + { + observer_->OnChange(); + } + DistributedRdb::RdbStoreObserver *getObserver() + { + return observer_; + } +private: + DistributedRdb::RdbStoreObserver *observer_ = nullptr; +}; + +class RdbStoreLocalSharedObserver : public AAFwk::DataAbilityObserverStub { +public: + explicit RdbStoreLocalSharedObserver(DistributedRdb::RdbStoreObserver *observer) : observer_(observer) {}; + virtual ~RdbStoreLocalSharedObserver() {}; + void OnChange() override + { + observer_->OnChange(); + } + DistributedRdb::RdbStoreObserver *getObserver() + { + return observer_; + } +private: + DistributedRdb::RdbStoreObserver *observer_ = nullptr; +}; + class RdbStoreImpl : public RdbStore, public std::enable_shared_from_this { public: RdbStoreImpl(const RdbStoreConfig &config, int &errCode); @@ -116,6 +152,8 @@ public: int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; + int Notify(const std::string &event) override; + // user must use UDID bool DropDeviceData(const std::vector& devices, const DropOption& option) override; @@ -141,6 +179,16 @@ private: std::map GetModifyTimeByRowId( const std::string &logTable, std::vector &keys); std::string GetSqlArgs(size_t size); + Uri GetUri(const std::string &event); + int SubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer); + int SubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer); + int SubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer); + + int UnSubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer); + int UnSubscribeLocalAll(const SubscribeOption& option); + int UnSubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer); + int UnSubscribeLocalSharedAll(const SubscribeOption& option); + int UnSubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer); const RdbStoreConfig rdbStoreConfig; SqliteConnectionPool *connectionPool; @@ -157,10 +205,14 @@ private: mutable std::shared_mutex rwMutex_; static inline constexpr uint32_t INTERVAL = 500; + static constexpr const char *ROW_ID = "ROWID"; std::set cloudTables_; std::mutex mutex_; std::shared_ptr> syncTables_; + static constexpr char SCHEME_RDB[] = "rdb://"; + std::map>> localObservers_; + std::map>> localSharedObservers_; }; } // namespace OHOS::NativeRdb #endif diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/include/sqlite_connection.h index 945f5ee1..460e6519 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection.h @@ -80,7 +80,8 @@ private: int RegDefaultFunctions(sqlite3 *dbHandle); static void MergeAssets(sqlite3_context *ctx, int argc, sqlite3_value **argv); - static void CompAssets(std::map &oldAssets, std::map &newAssets); + static void CompAssets(std::map &oldAssets, std::map &newAssets); static void MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Asset &newAsset); int SetCustomFunctions(const RdbStoreConfig &config); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h index 5c8200d2..4f972602 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h @@ -50,8 +50,6 @@ public: const std::string &group, const std::string &order, int limit, int offset); static std::string BuildSqlStringFromPredicatesNoWhere(const std::string &index, const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); - static std::string Normalize(const std::string &source, int &errorCode); - static std::string PredicatesNormalize(const std::string &source, int &errorCode); static std::string BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns); static std::string BuildCountString(const AbsRdbPredicates &predicates); static std::string BuildSqlStringFromPredicates(const AbsRdbPredicates &predicates); @@ -60,13 +58,6 @@ private: static void AppendClause(std::string &builder, const std::string &name, const std::string &clause); static void AppendColumns(std::string &builder, const std::vector &columns, int &errorCode); static void AppendExpr(std::string &builder, std::vector &exprs); - static bool IsNotEmptyString(const std::string &str); - static std::string NormalizeWords(const std::string &source, int &errorCode); - static std::string NormalizeTableColumn(const std::string &source, int &errorCode); - static std::string NormalizeMethodPattern(const std::string &source, int &errorCode); - static std::string NormalizeAlias(const std::string &source, int &errorCode); - static const std::string patternWords_; - static const std::string patternTableColumn_; }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/include/step_result_set.h b/relational_store/frameworks/native/rdb/include/step_result_set.h index c7c4c207..729d806e 100644 --- a/relational_store/frameworks/native/rdb/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/include/step_result_set.h @@ -81,7 +81,6 @@ private: static const int STEP_QUERY_RETRY_INTERVAL = 1000; SqliteConnection *connection_; std::vector columnNames_; - mutable std::shared_mutex mutex_; }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/include/string_utils.h b/relational_store/frameworks/native/rdb/include/string_utils.h index 88667b91..6ae11ec3 100644 --- a/relational_store/frameworks/native/rdb/include/string_utils.h +++ b/relational_store/frameworks/native/rdb/include/string_utils.h @@ -23,9 +23,9 @@ namespace OHOS { namespace NativeRdb { class StringUtils { public: - static std::string SurroundWithQuote(std::string value, std::string quote); + static std::string SurroundWithQuote(const std::string &value, const std::string "e); static std::string SurroundWithFunction( - std::string function, std::string separator, std::vector array); + const std::string &function, const std::string &separator, const std::vector &array); static bool IsEmpty(std::string source) { return (source.empty()); diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h index 5c8200d2..4f972602 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_sql_builder.h @@ -50,8 +50,6 @@ public: const std::string &group, const std::string &order, int limit, int offset); static std::string BuildSqlStringFromPredicatesNoWhere(const std::string &index, const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset); - static std::string Normalize(const std::string &source, int &errorCode); - static std::string PredicatesNormalize(const std::string &source, int &errorCode); static std::string BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns); static std::string BuildCountString(const AbsRdbPredicates &predicates); static std::string BuildSqlStringFromPredicates(const AbsRdbPredicates &predicates); @@ -60,13 +58,6 @@ private: static void AppendClause(std::string &builder, const std::string &name, const std::string &clause); static void AppendColumns(std::string &builder, const std::vector &columns, int &errorCode); static void AppendExpr(std::string &builder, std::vector &exprs); - static bool IsNotEmptyString(const std::string &str); - static std::string NormalizeWords(const std::string &source, int &errorCode); - static std::string NormalizeTableColumn(const std::string &source, int &errorCode); - static std::string NormalizeMethodPattern(const std::string &source, int &errorCode); - static std::string NormalizeAlias(const std::string &source, int &errorCode); - static const std::string patternWords_; - static const std::string patternTableColumn_; }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/mock/include/string_utils.h b/relational_store/frameworks/native/rdb/mock/include/string_utils.h index 88667b91..6ae11ec3 100644 --- a/relational_store/frameworks/native/rdb/mock/include/string_utils.h +++ b/relational_store/frameworks/native/rdb/mock/include/string_utils.h @@ -23,9 +23,9 @@ namespace OHOS { namespace NativeRdb { class StringUtils { public: - static std::string SurroundWithQuote(std::string value, std::string quote); + static std::string SurroundWithQuote(const std::string &value, const std::string "e); static std::string SurroundWithFunction( - std::string function, std::string separator, std::vector array); + const std::string &function, const std::string &separator, const std::vector &array); static bool IsEmpty(std::string source) { return (source.empty()); diff --git a/relational_store/frameworks/native/rdb/src/abs_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_predicates.cpp index ce7116e0..9cf1f152 100644 --- a/relational_store/frameworks/native/rdb/src/abs_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_predicates.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "logger.h" #include "rdb_trace.h" @@ -49,7 +50,7 @@ bool AbsPredicates::IsNeedAnd() const /** * Restricts the value of the field to be greater than the specified value. */ -AbsPredicates *AbsPredicates::EqualTo(std::string field, std::string value) +AbsPredicates *AbsPredicates::EqualTo(const std::string &field, const std::string &value) { DISTRIBUTED_DATA_HITRACE("AbsPredicates::EqualTo"); bool chekParaFlag = CheckParameter("equalTo", field, { value }); @@ -62,9 +63,7 @@ AbsPredicates *AbsPredicates::EqualTo(std::string field, std::string value) } else { isNeedAnd = true; } - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " = ? "; + whereClause += field + " = ? "; whereArgs.push_back(value); return this; } @@ -72,7 +71,7 @@ AbsPredicates *AbsPredicates::EqualTo(std::string field, std::string value) /** * Restricts the value of the field to be unequal to the specified value. */ -AbsPredicates *AbsPredicates::NotEqualTo(std::string field, std::string value) +AbsPredicates *AbsPredicates::NotEqualTo(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("notEqualTo", field, { value }); if (!chekParaFlag) { @@ -80,9 +79,7 @@ AbsPredicates *AbsPredicates::NotEqualTo(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " <> ? "; + whereClause += field + " <> ? "; whereArgs.push_back(value); return this; } @@ -130,7 +127,7 @@ AbsPredicates *AbsPredicates::And() /** * Restricts the value of the field to contain the specified string. */ -AbsPredicates *AbsPredicates::Contains(std::string field, std::string value) +AbsPredicates *AbsPredicates::Contains(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("contains", field, { value }); if (!chekParaFlag) { @@ -138,9 +135,7 @@ AbsPredicates *AbsPredicates::Contains(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " LIKE ? "; + whereClause += field + " LIKE ? "; whereArgs.push_back("%" + value + "%"); return this; } @@ -148,7 +143,7 @@ AbsPredicates *AbsPredicates::Contains(std::string field, std::string value) /** * Restricts the field to start with the specified string. */ -AbsPredicates *AbsPredicates::BeginsWith(std::string field, std::string value) +AbsPredicates *AbsPredicates::BeginsWith(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("beginsWith", field, { value }); if (!chekParaFlag) { @@ -156,9 +151,7 @@ AbsPredicates *AbsPredicates::BeginsWith(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " LIKE ? "; + whereClause += field + " LIKE ? "; whereArgs.push_back(value + "%"); return this; } @@ -166,7 +159,7 @@ AbsPredicates *AbsPredicates::BeginsWith(std::string field, std::string value) /** * Restricts the field to end with the specified string. */ -AbsPredicates *AbsPredicates::EndsWith(std::string field, std::string value) +AbsPredicates *AbsPredicates::EndsWith(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("endsWith", field, { value }); if (!chekParaFlag) { @@ -174,9 +167,7 @@ AbsPredicates *AbsPredicates::EndsWith(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " LIKE ? "; + whereClause += field + " LIKE ? "; whereArgs.push_back("%" + value); return this; } @@ -184,7 +175,7 @@ AbsPredicates *AbsPredicates::EndsWith(std::string field, std::string value) /** * Restricts the value of the field to be null. */ -AbsPredicates *AbsPredicates::IsNull(std::string field) +AbsPredicates *AbsPredicates::IsNull(const std::string &field) { bool chekParaFlag = CheckParameter("isNull", field, {}); if (!chekParaFlag) { @@ -192,16 +183,14 @@ AbsPredicates *AbsPredicates::IsNull(std::string field) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " is null "; + whereClause += field + " is null "; return this; } /** * estricts the value of the field not to be null. */ -AbsPredicates *AbsPredicates::IsNotNull(std::string field) +AbsPredicates *AbsPredicates::IsNotNull(const std::string &field) { bool chekParaFlag = CheckParameter("isNotNull", field, {}); if (!chekParaFlag) { @@ -209,16 +198,14 @@ AbsPredicates *AbsPredicates::IsNotNull(std::string field) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " is not null "; + whereClause += field + " is not null "; return this; } /** * Restricts the value of the field to have a pattern like field. */ -AbsPredicates *AbsPredicates::Like(std::string field, std::string value) +AbsPredicates *AbsPredicates::Like(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("like", field, { value }); if (!chekParaFlag) { @@ -226,9 +213,7 @@ AbsPredicates *AbsPredicates::Like(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " LIKE ? "; + whereClause += field + " LIKE ? "; whereArgs.push_back(value); return this; } @@ -236,7 +221,7 @@ AbsPredicates *AbsPredicates::Like(std::string field, std::string value) /** * Configures to match the specified field whose data type is String and the value contains a wildcard. */ -AbsPredicates *AbsPredicates::Glob(std::string field, std::string value) +AbsPredicates *AbsPredicates::Glob(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("glob", field, { value }); if (!chekParaFlag) { @@ -244,9 +229,7 @@ AbsPredicates *AbsPredicates::Glob(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " GLOB ? "; + whereClause += field + " GLOB ? "; whereArgs.push_back(value); return this; } @@ -262,9 +245,7 @@ AbsPredicates *AbsPredicates::Between(std::string field, std::string low, std::s return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " BETWEEN ? AND ? "; + whereClause += field + " BETWEEN ? AND ? "; whereArgs.push_back(low); whereArgs.push_back(high); return this; @@ -281,9 +262,7 @@ AbsPredicates *AbsPredicates::NotBetween(std::string field, std::string low, std return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " NOT BETWEEN ? AND ? "; + whereClause += field + " NOT BETWEEN ? AND ? "; whereArgs.push_back(low); whereArgs.push_back(high); return this; @@ -292,7 +271,7 @@ AbsPredicates *AbsPredicates::NotBetween(std::string field, std::string low, std /** * Restricts the value of the field to be greater than the specified value. */ -AbsPredicates *AbsPredicates::GreaterThan(std::string field, std::string value) +AbsPredicates *AbsPredicates::GreaterThan(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("greaterThan", field, { value }); if (!chekParaFlag) { @@ -300,9 +279,7 @@ AbsPredicates *AbsPredicates::GreaterThan(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " > ? "; + whereClause += field + " > ? "; whereArgs.push_back(value); return this; } @@ -310,7 +287,7 @@ AbsPredicates *AbsPredicates::GreaterThan(std::string field, std::string value) /** * Restricts the value of the field to be smaller than the specified value. */ -AbsPredicates *AbsPredicates::LessThan(std::string field, std::string value) +AbsPredicates *AbsPredicates::LessThan(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("lessThan", field, { value }); if (!chekParaFlag) { @@ -318,9 +295,7 @@ AbsPredicates *AbsPredicates::LessThan(std::string field, std::string value) return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " < ? "; + whereClause += field + " < ? "; whereArgs.push_back(value); return this; } @@ -328,7 +303,7 @@ AbsPredicates *AbsPredicates::LessThan(std::string field, std::string value) /** * Restricts the value of the field to be greater than or equal to the specified value. */ -AbsPredicates *AbsPredicates::GreaterThanOrEqualTo(std::string field, std::string value) +AbsPredicates *AbsPredicates::GreaterThanOrEqualTo(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("greaterThanOrEqualTo", field, { value }); if (!chekParaFlag) { @@ -336,9 +311,7 @@ AbsPredicates *AbsPredicates::GreaterThanOrEqualTo(std::string field, std::strin return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " >= ? "; + whereClause += field + " >= ? "; whereArgs.push_back(value); return this; } @@ -346,7 +319,7 @@ AbsPredicates *AbsPredicates::GreaterThanOrEqualTo(std::string field, std::strin /** * Restricts the value of the field to be smaller than or equal to the specified value. */ -AbsPredicates *AbsPredicates::LessThanOrEqualTo(std::string field, std::string value) +AbsPredicates *AbsPredicates::LessThanOrEqualTo(const std::string &field, const std::string &value) { bool chekParaFlag = CheckParameter("greaterThanOrEqualTo", field, { value }); if (!chekParaFlag) { @@ -354,9 +327,7 @@ AbsPredicates *AbsPredicates::LessThanOrEqualTo(std::string field, std::string v return this; } CheckIsNeedAnd(); - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - whereClause += normalizedField + " <= ? "; + whereClause += field + " <= ? "; whereArgs.push_back(value); return this; } @@ -365,7 +336,7 @@ AbsPredicates *AbsPredicates::LessThanOrEqualTo(std::string field, std::string v * Restricts the ascending order of the return list. When there are several orders, * the one close to the head has the highest priority. */ -AbsPredicates *AbsPredicates::OrderByAsc(std::string field) +AbsPredicates *AbsPredicates::OrderByAsc(const std::string &field) { bool chekParaFlag = CheckParameter("orderByAsc", field, {}); if (!chekParaFlag) { @@ -375,9 +346,7 @@ AbsPredicates *AbsPredicates::OrderByAsc(std::string field) if (isSorted) { order += ','; } - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - order += normalizedField + " ASC "; + order += field + " ASC "; isSorted = true; return this; } @@ -386,7 +355,7 @@ AbsPredicates *AbsPredicates::OrderByAsc(std::string field) * Restricts the descending order of the return list. When there are several orders, * the one close to the head has the highest priority. */ -AbsPredicates *AbsPredicates::OrderByDesc(std::string field) +AbsPredicates *AbsPredicates::OrderByDesc(const std::string &field) { bool chekParaFlag = CheckParameter("orderByDesc", field, {}); if (!chekParaFlag) { @@ -396,9 +365,7 @@ AbsPredicates *AbsPredicates::OrderByDesc(std::string field) if (isSorted) { order += ','; } - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::PredicatesNormalize(field, errorCode); - order += normalizedField + " DESC "; + order += field + " DESC "; isSorted = true; return this; } @@ -412,41 +379,39 @@ AbsPredicates *AbsPredicates::Distinct() /** * Restricts the max number of return records. */ -AbsPredicates *AbsPredicates::Limit(int value) +AbsPredicates *AbsPredicates::Limit(int limit) { - if (limit != -1) { - LOG_WARN("AbsPredicates limit(): limit cannot be set twice."); - return this; - } - if (value < 1) { - LOG_WARN("AbsPredicates limit(): limit cannot be less than or equal to zero."); - return this; - } - limit = value; + limit = (limit <= 0) ? -1 : limit; + this->limit = limit; return this; } +/** + * Restricts the max number of return records. + */ +AbsPredicates *AbsPredicates::Limit(int offset, int limit) +{ + limit = (limit <= 0) ? -1 : limit; + this->limit = limit; + + return Offset(offset); +} + /** * Configures to specify the start position of the returned result. */ -AbsPredicates *AbsPredicates::Offset(int rowOffset) +AbsPredicates *AbsPredicates::Offset(int offset) { - if (offset != -1) { - LOG_WARN("AbsPredicates offset(): offset cannot be set twice."); - return this; - } - if (rowOffset < 1) { - LOG_WARN("AbsPredicates offset(): the value of offset can't be less than or equal to zero."); - return this; - } - offset = rowOffset; + offset = (offset < 0) ? -1 : offset; + this->offset = offset; + return this; } /** * Configures {@code AbsPredicates} to group query results by specified columns. */ -AbsPredicates *AbsPredicates::GroupBy(std::vector fields) +AbsPredicates *AbsPredicates::GroupBy(const std::vector &fields) { if (fields.empty()) { LOG_WARN("AbsPredicates: groupBy() fails because fields can't be null."); @@ -458,9 +423,7 @@ AbsPredicates *AbsPredicates::GroupBy(std::vector fields) LOG_WARN("AbsPredicates: GroupBy() fails because Invalid parameter."); return this; } - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode); - group = group + normalizedField + ","; + group += field + ","; } size_t pos = group.find_last_of(","); if (pos != group.npos) { @@ -472,7 +435,7 @@ AbsPredicates *AbsPredicates::GroupBy(std::vector fields) /** * Configures {@code AbsPredicates} to specify the index column. */ -AbsPredicates *AbsPredicates::IndexedBy(std::string indexName) +AbsPredicates *AbsPredicates::IndexedBy(const std::string &indexName) { bool chekParaFlag = CheckParameter("indexedBy", indexName, {}); if (!chekParaFlag) { @@ -486,7 +449,7 @@ AbsPredicates *AbsPredicates::IndexedBy(std::string indexName) /** * Configures to match the specified field whose data type is String array and values are within a given range. */ -AbsPredicates *AbsPredicates::In(std::string field, std::vector values) +AbsPredicates *AbsPredicates::In(const std::string &field, const std::vector &values) { bool chekParaFlag = CheckParameter("in", field, {}); if (!chekParaFlag) { @@ -501,9 +464,9 @@ AbsPredicates *AbsPredicates::In(std::string field, std::vector val CheckIsNeedAnd(); std::vector replaceValues; - for (auto &i : values) { + for (auto &value : values) { replaceValues.push_back("?"); - whereArgs.push_back(i); + whereArgs.push_back(std::move(value)); } AppendWhereClauseWithInOrNotIn(" IN ", field, replaceValues); return this; @@ -512,7 +475,7 @@ AbsPredicates *AbsPredicates::In(std::string field, std::vector val /** * Configures to match the specified field whose data type is String array and values are out of a given range. */ -AbsPredicates *AbsPredicates::NotIn(std::string field, std::vector values) +AbsPredicates *AbsPredicates::NotIn(const std::string &field, const std::vector &values) { bool chekParaFlag = CheckParameter("notIn", field, {}); if (!chekParaFlag) { @@ -525,9 +488,9 @@ AbsPredicates *AbsPredicates::NotIn(std::string field, std::vector } CheckIsNeedAnd(); std::vector replaceValues; - for (auto &i : values) { + for (auto &value : values) { replaceValues.push_back("?"); - whereArgs.push_back(i); + whereArgs.push_back(std::move(value)); } AppendWhereClauseWithInOrNotIn(" NOT IN ", field, replaceValues); return this; @@ -543,22 +506,22 @@ void AbsPredicates::Initial() order.clear(); group.clear(); index.clear(); - limit = -1; - offset = -1; + limit = INT_MIN; + offset = INT_MIN; } /** * Check the parameter validity. */ bool AbsPredicates::CheckParameter( - std::string methodName, std::string field, std::initializer_list args) const + const std::string &methodName, const std::string &field, const std::initializer_list &args) const { if (field.empty()) { LOG_WARN("QueryImpl(): string 'field' is empty."); return false; } if (args.size() != 0) { - for (auto i : args) { + for (auto &i : args) { if (i.empty()) { LOG_WARN("QueryImpl(): value is empty."); return false; @@ -568,43 +531,16 @@ bool AbsPredicates::CheckParameter( return true; } -std::string AbsPredicates::RemoveQuotes(std::string source) const +std::string AbsPredicates::RemoveQuotes(const std::string &source) const { + std::string src = source; if (source.empty()) { return source; } - source.erase(std::remove(source.begin(), source.end(), '\''), source.end()); - source.erase(std::remove(source.begin(), source.end(), '\"'), source.end()); - source.erase(std::remove(source.begin(), source.end(), '`'), source.end()); - return source; -} - -std::string AbsPredicates::Normalized(std::string source) -{ - // split contains className, attributeName - const int splitSize = 2; - if (source.empty()) { - return source; - } - if (source.find(".") == source.npos) { - return StringUtils::SurroundWithQuote(source, "`"); - } - size_t pos = source.find("."); - size_t left = 0; - std::vector split; - while (pos != source.npos) { - split.push_back(source.substr(left, pos - left)); - left = pos + 1; - pos = source.find(".", left); - } - if (left < source.length()) { - split.push_back(source.substr(left)); - } - if (split.size() != splitSize) { - return source; - } - source = StringUtils::SurroundWithQuote(split[0], "`") + "." + StringUtils::SurroundWithQuote(split[1], "`"); - return source; + src.erase(std::remove(src.begin(), src.end(), '\''), src.end()); + src.erase(std::remove(src.begin(), src.end(), '\"'), src.end()); + src.erase(std::remove(src.begin(), src.end(), '`'), src.end()); + return src; } void AbsPredicates::CheckIsNeedAnd() @@ -617,11 +553,9 @@ void AbsPredicates::CheckIsNeedAnd() } void AbsPredicates::AppendWhereClauseWithInOrNotIn( - std::string methodName, std::string field, std::vector replaceValues) + const std::string &methodName, const std::string &field, const std::vector &replaceValues) { - int errorCode = 0; - std::string normalizedField = SqliteSqlBuilder::Normalize(field, errorCode); - whereClause += normalizedField + StringUtils::SurroundWithFunction(methodName, ",", replaceValues); + whereClause += field + StringUtils::SurroundWithFunction(methodName, ",", replaceValues); } std::string AbsPredicates::GetWhereClause() const @@ -629,7 +563,7 @@ std::string AbsPredicates::GetWhereClause() const return whereClause; } -void AbsPredicates::SetWhereClause(std::string whereClause) +void AbsPredicates::SetWhereClause(const std::string &whereClause) { if (whereClause.empty()) { return; @@ -642,7 +576,7 @@ std::vector AbsPredicates::GetWhereArgs() const return whereArgs; } -void AbsPredicates::SetWhereArgs(std::vector whereArgs) +void AbsPredicates::SetWhereArgs(const std::vector &whereArgs) { this->whereArgs = whereArgs; } @@ -652,7 +586,7 @@ std::string AbsPredicates::GetOrder() const return order; } -void AbsPredicates::SetOrder(std::string order) +void AbsPredicates::SetOrder(const std::string &order) { if (order.empty()) { return; diff --git a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp index 250a858c..14568a17 100644 --- a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp @@ -21,11 +21,11 @@ namespace OHOS::NativeRdb { using namespace OHOS::Rdb; -AbsRdbPredicates::AbsRdbPredicates(std::string tableName) +AbsRdbPredicates::AbsRdbPredicates(const std::string &tableName) { if (tableName.empty()) { tableName_ = ""; - LOG_INFO("no tableName specified."); + LOG_DEBUG("no tableName specified."); return; } tableName_ = std::move(tableName); @@ -34,11 +34,11 @@ AbsRdbPredicates::AbsRdbPredicates(std::string tableName) #endif } -AbsRdbPredicates::AbsRdbPredicates(std::vector tables) +AbsRdbPredicates::AbsRdbPredicates(const std::vector &tables) { if (tables.empty()) { tableName_ = ""; - LOG_INFO("no tableName specified."); + LOG_DEBUG("no tableName specified."); return; } tableName_ = *(tables.begin()); @@ -70,7 +70,7 @@ std::vector AbsRdbPredicates::GetJoinTypes() * Sets the join types in the predicates. The value can be {@code INNER JOIN}, {@code LEFT OUTER JOIN}, * and {@code CROSS JOIN}. */ -void AbsRdbPredicates::SetJoinTypes(const std::vector joinTypes) +void AbsRdbPredicates::SetJoinTypes(const std::vector &joinTypes) { this->joinTypes = joinTypes; } @@ -86,7 +86,7 @@ std::vector AbsRdbPredicates::GetJoinTableNames() /** * Sets the database table names of the joins in the predicates. */ -void AbsRdbPredicates::SetJoinTableNames(const std::vector joinTableNames) +void AbsRdbPredicates::SetJoinTableNames(const std::vector &joinTableNames) { this->joinTableNames = joinTableNames; } @@ -102,7 +102,7 @@ std::vector AbsRdbPredicates::GetJoinConditions() /** * Sets the join conditions required in the predicates. */ -void AbsRdbPredicates::SetJoinConditions(const std::vector joinConditions) +void AbsRdbPredicates::SetJoinConditions(const std::vector &joinConditions) { this->joinConditions = joinConditions; } @@ -179,14 +179,14 @@ const DistributedRdb::PredicatesMemo& AbsRdbPredicates::GetDistributedPredicates return predicates_; } -AbsRdbPredicates* AbsRdbPredicates::EqualTo(std::string field, std::string value) +AbsRdbPredicates* AbsRdbPredicates::EqualTo(const std::string &field, const std::string &value) { DISTRIBUTED_DATA_HITRACE("AbsRdbPredicates::EqualTo"); predicates_.AddOperation(DistributedRdb::EQUAL_TO, field, value); return (AbsRdbPredicates *)AbsPredicates::EqualTo(field, value); } -AbsRdbPredicates* AbsRdbPredicates::NotEqualTo(std::string field, std::string value) +AbsRdbPredicates* AbsRdbPredicates::NotEqualTo(const std::string &field, const std::string &value) { predicates_.AddOperation(DistributedRdb::NOT_EQUAL_TO, field, value); return (AbsRdbPredicates *)AbsPredicates::NotEqualTo(field, value); @@ -208,14 +208,14 @@ AbsRdbPredicates* AbsRdbPredicates::Or() return (AbsRdbPredicates *)AbsPredicates::Or(); } -AbsRdbPredicates* AbsRdbPredicates::OrderByAsc(std::string field) +AbsRdbPredicates* AbsRdbPredicates::OrderByAsc(const std::string &field) { std::string isAsc = "true"; predicates_.AddOperation(DistributedRdb::ORDER_BY, field, isAsc); return (AbsRdbPredicates *)AbsPredicates::OrderByAsc(field); } -AbsRdbPredicates* AbsRdbPredicates::OrderByDesc(std::string field) +AbsRdbPredicates* AbsRdbPredicates::OrderByDesc(const std::string &field) { std::string isAsc = "false"; predicates_.AddOperation(DistributedRdb::ORDER_BY, field, isAsc); diff --git a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp index cfa6ce35..244ef420 100644 --- a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp @@ -216,7 +216,7 @@ int AbsResultSet::GoToFirstRow() DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int ret = GoToRow(0); if (ret != E_OK) { - LOG_WARN("GoToRow ret is %{public}d", ret); + LOG_DEBUG("GoToRow ret is %{public}d", ret); return ret; } return E_OK; @@ -245,7 +245,7 @@ int AbsResultSet::GoToNextRow() DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int ret = GoToRow(rowPos_ + 1); if (ret != E_OK) { - LOG_WARN("GoToRow ret is %{public}d", ret); + LOG_DEBUG("GoToRow ret is %{public}d", ret); return ret; } return E_OK; diff --git a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp index 3f96739f..83ada7e7 100644 --- a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp @@ -33,9 +33,8 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -AbsSharedResultSet::AbsSharedResultSet(std::string name) +AbsSharedResultSet::AbsSharedResultSet(std::string name) : sharedBlock_(nullptr), sharedBlockName_(name) { - AppDataFwk::SharedBlock::Create(name, DEFAULT_BLOCK_SIZE, sharedBlock_); } AbsSharedResultSet::AbsSharedResultSet() @@ -67,11 +66,20 @@ void AbsSharedResultSet::FillBlock(int startRowIndex, AppDataFwk::SharedBlock *b return; } +void AbsSharedResultSet::InitBlock() +{ + if (sharedBlock_ == nullptr) { + AppDataFwk::SharedBlock::Create(sharedBlockName_, DEFAULT_BLOCK_SIZE, sharedBlock_); + } + return; +} + /** * Get current shared block */ -AppDataFwk::SharedBlock *AbsSharedResultSet::GetBlock() const +AppDataFwk::SharedBlock *AbsSharedResultSet::GetBlock() { + InitBlock(); return sharedBlock_; } @@ -82,7 +90,7 @@ int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType) return errorCode; } AppDataFwk::SharedBlock::CellUnit *cellUnit = - sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), (uint32_t)columnIndex); + GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), (uint32_t)columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetColumnType cellUnit is null!"); return E_ERROR; @@ -106,7 +114,7 @@ int AbsSharedResultSet::GoToRow(int position) int rowCnt = 0; GetRowCount(rowCnt); if (rowCnt == 0) { - LOG_WARN("No data!"); + LOG_DEBUG("No data!"); return E_ERROR; } @@ -118,12 +126,13 @@ int AbsSharedResultSet::GoToRow(int position) if (rowPos_ <= INIT_POS) { rowPos_ = 0; } + bool result = true; - if (sharedBlock_ == nullptr || (uint32_t)position < sharedBlock_->GetStartPos() || - (uint32_t)position >= sharedBlock_->GetLastPos() || rowPos_ == rowCnt) { + if (GetBlock() == nullptr || (uint32_t)position < GetBlock()->GetStartPos() || + (uint32_t)position >= GetBlock()->GetLastPos() || rowPos_ == rowCnt) { result = OnGo(rowPos_, position); } else { - uint32_t blockPos = sharedBlock_->GetBlockPos(); + uint32_t blockPos = GetBlock()->GetBlockPos(); if (position > rowPos_) { blockPos += (uint32_t)(position - rowPos_); } else { @@ -135,7 +144,7 @@ int AbsSharedResultSet::GoToRow(int position) return E_ERROR; } } - sharedBlock_->SetBlockPos(blockPos); + GetBlock()->SetBlockPos(blockPos); } if (result) { @@ -153,7 +162,7 @@ int AbsSharedResultSet::GetBlob(int columnIndex, std::vector &value) return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetBlob cellUnit is null!"); return E_ERROR; @@ -164,7 +173,7 @@ int AbsSharedResultSet::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(GetBlock()->GetCellUnitValueBlob(cellUnit, &size)); if (size == 0 || blob == nullptr) { LOG_WARN("blob data is empty!"); } else { @@ -200,7 +209,7 @@ int AbsSharedResultSet::GetString(int columnIndex, std::string &value) if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetString cellUnit is null!"); return E_ERROR; @@ -208,7 +217,7 @@ int AbsSharedResultSet::GetString(int columnIndex, std::string &value) int type = cellUnit->type; if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) { size_t sizeIncludingNull; - const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull); + const char *tempValue = GetBlock()->GetCellUnitValueString(cellUnit, &sizeIncludingNull); if ((sizeIncludingNull <= 1) || (tempValue == nullptr)) { value = ""; return E_OK; @@ -248,7 +257,7 @@ int AbsSharedResultSet::GetInt(int columnIndex, int &value) if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetInt cellUnit is null!"); return E_ERROR; @@ -264,7 +273,7 @@ int AbsSharedResultSet::GetLong(int columnIndex, int64_t &value) if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetLong cellUnit is null!"); return E_ERROR; @@ -277,7 +286,7 @@ int AbsSharedResultSet::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 = GetBlock()->GetCellUnitValueString(cellUnit, &sizeIncludingNull); value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? int64_t(strtoll(tempValue, nullptr, 0)) : 0L; return E_OK; } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) { @@ -308,7 +317,7 @@ int AbsSharedResultSet::GetDouble(int columnIndex, double &value) if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetDouble cellUnit is null!"); return E_ERROR; @@ -319,7 +328,7 @@ int AbsSharedResultSet::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 = GetBlock()->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) { @@ -354,7 +363,7 @@ int AbsSharedResultSet::GetAsset(int32_t col, ValueObject::Asset &value) return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), col); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), col); if (!cellUnit) { LOG_ERROR("GetAsset cellUnit is null!"); return E_ERROR; @@ -372,7 +381,7 @@ int AbsSharedResultSet::GetAsset(int32_t col, ValueObject::Asset &value) } size_t size = 0; - auto data = reinterpret_cast(sharedBlock_->GetCellUnitValueBlob(cellUnit, &size)); + auto data = reinterpret_cast(GetBlock()->GetCellUnitValueBlob(cellUnit, &size)); ValueObject::Asset asset; RawDataParser::ParserRawData(data, size, asset); value = std::move(asset); @@ -387,7 +396,7 @@ int AbsSharedResultSet::GetAssets(int32_t col, ValueObject::Assets &value) return errorCode; } - auto *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), col); + auto *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), col); if (!cellUnit) { LOG_ERROR("GetAssets cellUnit is null!"); return E_ERROR; @@ -405,7 +414,7 @@ int AbsSharedResultSet::GetAssets(int32_t col, ValueObject::Assets &value) } size_t size = 0; - auto data = reinterpret_cast(sharedBlock_->GetCellUnitValueBlob(cellUnit, &size)); + auto data = reinterpret_cast(GetBlock()->GetCellUnitValueBlob(cellUnit, &size)); ValueObject::Assets assets; RawDataParser::ParserRawData(data, size, assets); value = std::move(assets); @@ -420,7 +429,7 @@ int AbsSharedResultSet::GetSize(int columnIndex, size_t &size) return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (cellUnit == nullptr) { LOG_ERROR("cellUnit is null!"); return E_ERROR; @@ -430,7 +439,7 @@ int AbsSharedResultSet::GetSize(int columnIndex, size_t &size) if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) { - sharedBlock_->GetCellUnitValueBlob(cellUnit, &size); + GetBlock()->GetCellUnitValueBlob(cellUnit, &size); return E_OK; } @@ -443,7 +452,7 @@ int AbsSharedResultSet::IsColumnNull(int columnIndex, bool &isNull) if (errorCode != E_OK) { return errorCode; } - AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex); + AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::IsColumnNull cellUnit is null!"); return E_ERROR; @@ -458,7 +467,6 @@ int AbsSharedResultSet::IsColumnNull(int columnIndex, bool &isNull) int AbsSharedResultSet::Close() { - std::unique_lock lock(mutex_); if (!isClosed) { AbsResultSet::Close(); ClosedBlock(); @@ -471,7 +479,7 @@ int AbsSharedResultSet::Close() */ void AbsSharedResultSet::SetBlock(AppDataFwk::SharedBlock *block) { - if (sharedBlock_ != block) { + if (GetBlock() != block) { ClosedBlock(); sharedBlock_ = block; } @@ -480,9 +488,9 @@ void AbsSharedResultSet::SetBlock(AppDataFwk::SharedBlock *block) /** * Checks whether an {@code AbsSharedResultSet} object contains shared blocks */ -bool AbsSharedResultSet::HasBlock() const +bool AbsSharedResultSet::HasBlock() { - return sharedBlock_ != nullptr; + return GetBlock() != nullptr; } /** @@ -490,14 +498,16 @@ bool AbsSharedResultSet::HasBlock() const */ void AbsSharedResultSet::ClosedBlock() { - delete sharedBlock_; - sharedBlock_ = nullptr; + if (sharedBlock_ != nullptr) { + delete sharedBlock_; + sharedBlock_ = nullptr; + } } void AbsSharedResultSet::ClearBlock() { - if (sharedBlock_ != nullptr) { - sharedBlock_->Clear(); + if (GetBlock() != nullptr) { + GetBlock()->Clear(); } } @@ -511,7 +521,7 @@ void AbsSharedResultSet::Finalize() */ int AbsSharedResultSet::CheckState(int columnIndex) { - if (sharedBlock_ == nullptr) { + if (GetBlock() == nullptr) { LOG_ERROR("AbsSharedResultSet::CheckState sharedBlock is null!"); return E_ERROR; } diff --git a/relational_store/frameworks/native/rdb/src/rdb_predicates.cpp b/relational_store/frameworks/native/rdb/src/rdb_predicates.cpp index dd36cfee..f373a77b 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_predicates.cpp @@ -17,12 +17,13 @@ #include "logger.h" #include "string_utils.h" +#include "sqlite_sql_builder.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -RdbPredicates::RdbPredicates(std::string tableName) : AbsRdbPredicates(tableName) +RdbPredicates::RdbPredicates(const std::string &tableName) : AbsRdbPredicates(tableName) { InitialParam(); } @@ -38,7 +39,7 @@ std::string RdbPredicates::GetJoinClause() const /** * Adds a {@code cross join} condition to a SQL statement. */ -RdbPredicates *RdbPredicates::CrossJoin(std::string tableName) +RdbPredicates *RdbPredicates::CrossJoin(const std::string &tableName) { return Join(JoinType::CROSS, tableName); } @@ -46,7 +47,7 @@ RdbPredicates *RdbPredicates::CrossJoin(std::string tableName) /** * Adds an {@code inner join} condition to a SQL statement. */ -RdbPredicates *RdbPredicates::InnerJoin(std::string tableName) +RdbPredicates *RdbPredicates::InnerJoin(const std::string &tableName) { return Join(JoinType::INNER, tableName); } @@ -54,14 +55,14 @@ RdbPredicates *RdbPredicates::InnerJoin(std::string tableName) /** * Adds a {@code left outer join} condition to a SQL statement. */ -RdbPredicates *RdbPredicates::LeftOuterJoin(std::string tableName) +RdbPredicates *RdbPredicates::LeftOuterJoin(const std::string &tableName) { return Join(JoinType::LEFT, tableName); } /** * Adds a condition to a SQL statement. */ -RdbPredicates *RdbPredicates::Join(int join, std::string tableName) +RdbPredicates *RdbPredicates::Join(int join, const std::string &tableName) { if (tableName.empty()) { LOG_WARN("RdbPredicates join failed: table name is null or empty."); @@ -77,7 +78,7 @@ RdbPredicates *RdbPredicates::Join(int join, std::string tableName) /** * Adds a {@code using} condition to the predicate. This method is similar to {@code using} of the SQL statement. */ -RdbPredicates *RdbPredicates::Using(std::vector fields) +RdbPredicates *RdbPredicates::Using(const std::vector &fields) { if (fields.size() == 0) { LOG_WARN("RdbPredicates Using failed : clauses is null."); @@ -99,7 +100,7 @@ RdbPredicates *RdbPredicates::Using(std::vector fields) /** * Adds an {@code on} condition to the predicate. */ -RdbPredicates *RdbPredicates::On(std::vector clauses) +RdbPredicates *RdbPredicates::On(const std::vector &clauses) { if (clauses.size() == 0) { LOG_WARN("RdbPredicates on failed : clauses is null."); @@ -118,6 +119,16 @@ RdbPredicates *RdbPredicates::On(std::vector clauses) return this; } +std::string RdbPredicates::GetStatement() +{ + return SqliteSqlBuilder::BuildSqlStringFromPredicates(*this); +} + +std::vector RdbPredicates::GetBindArgs() +{ + return GetWhereArgs(); +} + std::string RdbPredicates::ProcessJoins() const { std::string builder = GetTableName(); diff --git a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp index 6856f87d..bb339664 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -83,14 +83,7 @@ void RdbServiceProxy::OnDataChange(const Origin &origin, const PrimaryFields &pr std::string RdbServiceProxy::ObtainDistributedTableName(const std::string &device, const std::string &table) { - MessageParcel reply; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_OBTAIN_TABLE), reply, device, table); - if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, device:%{public}.6s, table:%{public}s", status, - SqliteUtils::Anonymous(device).c_str(), SqliteUtils::Anonymous(table).c_str()); - return ""; - } - return reply.ReadString(); + return ""; } int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam ¶m) @@ -351,4 +344,4 @@ int32_t RdbServiceProxy::GetSchema(const RdbSyncerParam ¶m) } return status; } -} // namespace OHOS::DistributedRdb +} // namespace OHOS::DistributedRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp index c58ccd4b..20b8f691 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -14,7 +14,6 @@ */ #include -#include #include #include @@ -22,58 +21,32 @@ #ifdef WINDOWS_PLATFORM #include #endif -#include -#include "logger.h" #include "rdb_errno.h" #include "rdb_sql_utils.h" #include "sqlite_sql_builder.h" #ifdef WINDOWS_PLATFORM -#define REALPATH(relPath, absPath, ...) (_fullpath(absPath, relPath, ##__VA_ARGS__)) #define MKDIR(filePath) (mkdir(filePath)) #else -#define REALPATH(absPath, relPath, ...) (realpath(absPath, relPath)) #define MKDIR(filePath) (mkdir(filePath, 0771)) #endif namespace OHOS { namespace NativeRdb { -using namespace OHOS::Rdb; /** * Get and Check default path. */ std::string RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, int &errorCode) { - if (access(baseDir.c_str(), F_OK) != 0) { - if (MKDIR(baseDir.c_str())) { - errorCode = E_CREATE_FOLDER_FAIL; - } - } -#if defined(WINDOWS_PLATFORM) - std::string databasePath = baseDir + "\\rdb"; -#else std::string databasePath = baseDir + "/rdb"; -#endif if (access(databasePath.c_str(), F_OK) != 0) { if (MKDIR(databasePath.c_str())) { errorCode = E_CREATE_FOLDER_FAIL; } } - char canonicalPath[PATH_MAX + 1] = { 0 }; - if (REALPATH(databasePath.c_str(), canonicalPath, PATH_MAX) == nullptr) { - LOG_ERROR("Failed to obtain real path, errno:%{public}d", errno); - errorCode = E_INVALID_FILE_PATH; - return ""; - } - std::string realFilePath(canonicalPath); -#if defined(WINDOWS_PLATFORM) - realFilePath = realFilePath.append("\\").append(name); -#else - realFilePath = realFilePath.append("/").append(name); -#endif - return realFilePath; + return databasePath.append("/").append(name); } std::string RdbSqlUtils::BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns) diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp index 9960b130..200db050 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp @@ -388,4 +388,14 @@ std::map RdbStoreConfig::GetScalarFunctions() c { return customScalarFunctions; } + +void RdbStoreConfig::SetDataGroupId(const std::string &DataGroupId) +{ + dataGroupId_ = DataGroupId; +} + +std::string RdbStoreConfig::GetDataGroupId() const +{ + return dataGroupId_; +} } // namespace OHOS::NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp index bf73df71..934dc2a1 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -58,7 +58,7 @@ using namespace OHOS::Rdb; int RdbStoreImpl::InnerOpen() { - LOG_INFO("open %{public}s.", SqliteUtils::Anonymous(rdbStoreConfig.GetPath()).c_str()); + LOG_DEBUG("open %{public}s.", SqliteUtils::Anonymous(rdbStoreConfig.GetPath()).c_str()); int errCode = E_OK; connectionPool = SqliteConnectionPool::Create(rdbStoreConfig, errCode); if (connectionPool == nullptr) { @@ -99,7 +99,7 @@ void RdbStoreImpl::GetSchema(const RdbStoreConfig &config) pool_->Execute([param]() { auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); if (err != E_OK || service == nullptr) { - LOG_WARN("GetRdbService failed, err is %{public}d.", err); + LOG_DEBUG("GetRdbService failed, err is %{public}d.", err); return; } err = service->GetSchema(param); @@ -119,7 +119,7 @@ std::map RdbStoreImpl::GetModifyTime( } auto logTable = DistributedDB::RelationalStoreManager::GetDistributedLogTableName(table); - if (columnName == "rowid") { + if (SqliteUtils::StrToUpper(columnName) == ROW_ID) { return GetModifyTimeByRowId(logTable, keys); } std::vector hashKeys; @@ -224,7 +224,7 @@ RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config, int &errCode) RdbStoreImpl::~RdbStoreImpl() { - LOG_INFO("destroy."); + LOG_DEBUG("destroy."); if (connectionPool) { delete connectionPool; } @@ -631,7 +631,7 @@ int RdbStoreImpl::ExecuteSql(const std::string &sql, const std::vectorReOpenAvailableReadConnections(); } @@ -1383,7 +1383,61 @@ int RdbStoreImpl::Sync(const SyncOption &option, const std::vector return E_OK; } -int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) +Uri RdbStoreImpl::GetUri(const std::string &event) +{ + std::string rdbUri; + if (rdbStoreConfig.GetDataGroupId().empty()) { + rdbUri = SCHEME_RDB + rdbStoreConfig.GetBundleName() + "/" + path + "/" + event; + } else { + rdbUri = SCHEME_RDB + rdbStoreConfig.GetDataGroupId() + "/" + path + "/" + event; + } + return Uri(rdbUri); +} + +int RdbStoreImpl::SubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer) +{ + std::lock_guard lock(mutex_); + localObservers_.try_emplace(option.event); + auto &list = localObservers_.find(option.event)->second; + for (auto it = list.begin(); it != list.end(); it++) { + if ((*it)->getObserver() == observer) { + LOG_ERROR("duplicate subscribe"); + return E_OK; + } + } + + localObservers_[option.event].push_back(std::make_shared(observer)); + return E_OK; +} + +int RdbStoreImpl::SubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer) +{ + std::lock_guard lock(mutex_); + localSharedObservers_.try_emplace(option.event); + auto &list = localSharedObservers_.find(option.event)->second; + for (auto it = list.begin(); it != list.end(); it++) { + if ((*it)->getObserver() == observer) { + LOG_ERROR("duplicate subscribe"); + return E_OK; + } + } + + auto client = OHOS::AAFwk::DataObsMgrClient::GetInstance(); + if (client == nullptr) { + LOG_ERROR("Failed to get DataObsMgrClient."); + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + sptr localSharedObserver(new (std::nothrow) RdbStoreLocalSharedObserver(observer)); + int32_t err = client->RegisterObserver(GetUri(option.event), localSharedObserver); + if (err != 0) { + LOG_ERROR("Subscribe failed."); + return err; + } + localSharedObservers_[option.event].push_back(std::move(localSharedObserver)); + return E_OK; +} + +int RdbStoreImpl::SubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) { auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { @@ -1392,9 +1446,114 @@ int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *obs return service->Subscribe(syncerParam_, option, observer); } -int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) +int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) +{ + if (option.mode == SubscribeMode::LOCAL) { + return SubscribeLocal(option, observer); + } + if (option.mode == SubscribeMode::LOCAL_SHARED) { + return SubscribeLocalShared(option, observer); + } + return SubscribeRemote(option, observer); +} + +int RdbStoreImpl::UnSubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer) +{ + std::lock_guard lock(mutex_); + auto obs = localObservers_.find(option.event); + if (obs == localObservers_.end()) { + return E_OK; + } + + auto &list = obs->second; + for (auto it = list.begin(); it != list.end(); it++) { + if ((*it)->getObserver() == observer) { + it = list.erase(it); + break; + } + } + + if (list.empty()) { + localObservers_.erase(option.event); + } + return E_OK; +} + +int RdbStoreImpl::UnSubscribeLocalAll(const SubscribeOption& option) +{ + std::lock_guard lock(mutex_); + auto obs = localObservers_.find(option.event); + if (obs == localObservers_.end()) { + return E_OK; + } + + localObservers_.erase(option.event); + return E_OK; +} + +int RdbStoreImpl::UnSubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer) +{ + std::lock_guard lock(mutex_); + auto obs = localSharedObservers_.find(option.event); + if (obs == localSharedObservers_.end()) { + return E_OK; + } + + auto client = OHOS::AAFwk::DataObsMgrClient::GetInstance(); + if (client == nullptr) { + LOG_ERROR("Failed to get DataObsMgrClient."); + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + + auto &list = obs->second; + for (auto it = list.begin(); it != list.end(); it++) { + if ((*it)->getObserver() == observer) { + int32_t err = client->UnregisterObserver(GetUri(option.event), *it); + if (err != 0) { + LOG_ERROR("UnSubscribeLocalShared failed."); + return err; + } + list.erase(it); + break; + } + } + if (list.empty()) { + localSharedObservers_.erase(option.event); + } + return E_OK; +} + +int RdbStoreImpl::UnSubscribeLocalSharedAll(const SubscribeOption& option) +{ + std::lock_guard lock(mutex_); + auto obs = localSharedObservers_.find(option.event); + if (obs == localSharedObservers_.end()) { + return E_OK; + } + + auto client = OHOS::AAFwk::DataObsMgrClient::GetInstance(); + if (client == nullptr) { + LOG_ERROR("Failed to get DataObsMgrClient."); + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + + auto &list = obs->second; + auto it = list.begin(); + while (it != list.end()) { + int32_t err = client->UnregisterObserver(GetUri(option.event), *it); + if (err != 0) { + LOG_ERROR("UnSubscribe failed."); + return err; + } + it = list.erase(it); + } + + localSharedObservers_.erase(option.event); + return E_OK; +} + +int RdbStoreImpl::UnSubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) { - LOG_INFO("enter"); auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; @@ -1402,6 +1561,43 @@ int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *o return service->UnSubscribe(syncerParam_, option, observer); } +int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) +{ + if (option.mode == SubscribeMode::LOCAL && observer) { + return UnSubscribeLocal(option, observer); + } else if (option.mode == SubscribeMode::LOCAL && !observer) { + return UnSubscribeLocalAll(option); + } else if (option.mode == SubscribeMode::LOCAL_SHARED && observer) { + return UnSubscribeLocalShared(option, observer); + } else if (option.mode == SubscribeMode::LOCAL_SHARED && !observer) { + return UnSubscribeLocalSharedAll(option); + } + return UnSubscribeRemote(option, observer); +} + +int RdbStoreImpl::Notify(const std::string &event) +{ + auto client = OHOS::AAFwk::DataObsMgrClient::GetInstance(); + if (client == nullptr) { + LOG_ERROR("Failed to get DataObsMgrClient."); + return E_GET_DATAOBSMGRCLIENT_FAIL; + } + int32_t err = client->NotifyChange(GetUri(event)); + if (err != 0) { + LOG_ERROR("Notify failed."); + } + + std::lock_guard lock(mutex_); + auto obs = localObservers_.find(event); + if (obs != localObservers_.end()) { + auto &list = obs->second; + for (auto &it : list) { + it->OnChange(); + } + } + return E_OK; +} + bool RdbStoreImpl::DropDeviceData(const std::vector &devices, const DropOption &option) { LOG_INFO("not implement"); diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index 3ec43aed..a71f6cd6 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -24,8 +24,10 @@ #include "rdb_trace.h" #include "sqlite_global_config.h" -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) +#if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) #include "rdb_security_manager.h" +#endif #include "security_policy.h" #endif #include "sqlite_utils.h" @@ -64,7 +66,7 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con std::shared_ptr rdbStore(new (std::nothrow) RdbStoreImpl(config, errCode), [](RdbStoreImpl *ptr) { - LOG_INFO("delete %{public}s as no more used.", SqliteUtils::Anonymous(ptr->GetPath()).c_str()); + LOG_DEBUG("delete %{public}s as no more used.", SqliteUtils::Anonymous(ptr->GetPath()).c_str()); delete ptr; }); if (errCode != E_OK) { @@ -156,7 +158,7 @@ int RdbStoreManager::ProcessOpenCallback( } int RdbStoreManager::SetSecurityLabel(const RdbStoreConfig &config) { -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) return SecurityPolicy::SetSecurityLabel(config); #endif return E_OK; diff --git a/relational_store/frameworks/native/rdb/src/security_policy.cpp b/relational_store/frameworks/native/rdb/src/security_policy.cpp index e59e00b3..074c6411 100644 --- a/relational_store/frameworks/native/rdb/src/security_policy.cpp +++ b/relational_store/frameworks/native/rdb/src/security_policy.cpp @@ -17,7 +17,7 @@ #include "logger.h" #include "rdb_errno.h" -#include "security_label.h" +#include "filemanagement/file_api/interfaces/kits/security_label.h" namespace OHOS { namespace NativeRdb { @@ -25,7 +25,7 @@ using namespace OHOS::Rdb; int SecurityPolicy::SetFileSecurityLevel(const std::string &filePath, const std::string &securityLevel) { - bool result = DistributedFS::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(filePath, securityLevel); + bool result = FileManagement::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(filePath, securityLevel); LOG_INFO("Set database securityLabel:%{public}s, result:%{public}d.", securityLevel.c_str(), result); return result ? E_OK : E_ERROR; } @@ -48,7 +48,7 @@ std::string SecurityPolicy::GetSecurityLevelValue(SecurityLevel securityLevel) std::string SecurityPolicy::GetFileSecurityLevel(const std::string &filePath) { - return DistributedFS::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); + return FileManagement::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); } int SecurityPolicy::SetSecurityLabel(const RdbStoreConfig &config) diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index 6f948b7b..823f4fe1 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -262,7 +262,7 @@ SqliteConnection::~SqliteConnection() if (stepStatement != nullptr) { stepStatement->Finalize(); } - int errCode = sqlite3_close(dbHandle); + int errCode = sqlite3_close_v2(dbHandle); if (errCode != SQLITE_OK) { LOG_ERROR("SqliteConnection ~SqliteConnection: could not close database err = %{public}d", errCode); } @@ -689,6 +689,9 @@ int SqliteConnection::ExecuteGetString( std::shared_ptr SqliteConnection::BeginStepQuery( int &errCode, const std::string &sql, const std::vector &selectionArgs) const { + if (!stepStatement) { + return nullptr; + } errCode = stepStatement->Prepare(dbHandle, sql); if (errCode != E_OK) { return nullptr; @@ -945,6 +948,9 @@ void SqliteConnection::CompAssets(std::map &ass if (oldIt->first == newIt->first) { if (newIt->second.status == Status::STATUS_DELETE) { oldIt->second.status = Status::STATUS_DELETE; + oldIt->second.hash = ""; + oldIt->second.modifyTime = ""; + oldIt->second.size = ""; } else { MergeAsset(oldIt->second, newIt->second); } @@ -956,7 +962,7 @@ void SqliteConnection::CompAssets(std::map &ass ++oldIt; continue; } - newIt = newAssets.erase(newIt); + newIt++; } for (auto &[key, value] : newAssets) { value.status = ValueObject::Asset::Status::STATUS_INSERT; @@ -986,6 +992,7 @@ void SqliteConnection::MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Ass oldAsset.path = newAsset.path; oldAsset.status = Status ::STATUS_UPDATE; } + return; default: return; } diff --git a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp index 7bb38d3f..c2c9c4bc 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp @@ -36,7 +36,6 @@ SqliteSharedResultSet::SqliteSharedResultSet(std::shared_ptr store } SqliteSharedResultSet::~SqliteSharedResultSet() { - store_.reset(); } std::shared_ptr SqliteSharedResultSet::PrepareStep(SqliteConnection* connection, int &errCode) @@ -58,7 +57,6 @@ std::shared_ptr SqliteSharedResultSet::PrepareStep(SqliteConnec int SqliteSharedResultSet::GetAllColumnNames(std::vector &columnNames) { - std::shared_lock readLock(mutex_); if (!columnNames_.empty()) { columnNames = columnNames_; return E_OK; @@ -110,7 +108,6 @@ int SqliteSharedResultSet::GetAllColumnNames(std::vector &columnNam int SqliteSharedResultSet::GetRowCount(int &count) { - std::shared_lock lock(mutex_); if (rowNum != NO_COUNT) { count = rowNum; return E_OK; @@ -156,11 +153,6 @@ void SqliteSharedResultSet::FillSharedBlock(int requiredPos) { ClearBlock(); - if (!HasBlock()) { - LOG_ERROR("SqliteSharedResultSet::FillSharedBlock sharedBlock is null."); - return; - } - std::vector bindArgs; size_t size = selectionArgVec.size(); bindArgs.reserve(size); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp index 3f2b1df2..7b99651a 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp @@ -15,8 +15,7 @@ #include "sqlite_sql_builder.h" -#include -#include +#include #include "logger.h" #include "rdb_errno.h" @@ -26,10 +25,6 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; - -const std::string SqliteSqlBuilder::patternWords_ = "['\"`]?(\\w+)['\"`]?|['\"`]([^`\"']+)['\"`]"; -const std::string SqliteSqlBuilder::patternTableColumn_ = "(" + patternWords_ + ")[.](" + patternWords_ + "|\\*)"; - std::vector g_onConflictClause = { "", " OR ROLLBACK", " OR ABORT", " OR FAIL", " OR IGNORE", " OR REPLACE" }; @@ -176,8 +171,8 @@ std::string SqliteSqlBuilder::BuildSqlStringFromPredicates(const std::string &in { std::string sqlString; - std::string limitStr = (limit == -1) ? "" : std::to_string(limit); - std::string offsetStr = (offset == -1) ? "" : std::to_string(offset); + std::string limitStr = (limit == INT_MIN) ? "" : std::to_string(limit); + std::string offsetStr = (offset == INT_MIN) ? "" : std::to_string(offset); AppendClause(sqlString, " INDEXED BY ", index); AppendClause(sqlString, " WHERE ", whereClause); @@ -193,8 +188,8 @@ std::string SqliteSqlBuilder::BuildSqlStringFromPredicates(const AbsRdbPredicate { std::string sqlString; - std::string limitStr = (predicates.GetLimit() == -1) ? "" : std::to_string(predicates.GetLimit()); - std::string offsetStr = (predicates.GetOffset() == -1) ? "" : std::to_string(predicates.GetOffset()); + std::string limitStr = (predicates.GetLimit() == INT_MIN) ? "" : std::to_string(predicates.GetLimit()); + std::string offsetStr = (predicates.GetOffset() == INT_MIN) ? "" : std::to_string(predicates.GetOffset()); AppendClause(sqlString, " INDEXED BY ", predicates.GetIndex()); AppendClause(sqlString, " WHERE ", predicates.GetWhereClause()); @@ -210,8 +205,8 @@ std::string SqliteSqlBuilder::BuildSqlStringFromPredicatesNoWhere(const std::str const std::string &whereClause, const std::string &group, const std::string &order, int limit, int offset) { std::string sqlString; - std::string limitStr = (limit == -1) ? "" : std::to_string(limit); - std::string offsetStr = (offset == -1) ? "" : std::to_string(offset); + std::string limitStr = (limit == INT_MIN) ? "" : std::to_string(limit); + std::string offsetStr = (offset == INT_MIN) ? "" : std::to_string(offset); AppendClause(sqlString, " INDEXED BY ", index); AppendClause(sqlString, " ", whereClause); @@ -245,7 +240,7 @@ void SqliteSqlBuilder::AppendColumns(std::string &builder, const std::vector 0) { builder.append(", "); } - builder.append(NormalizeAlias(column, errorCode)); + builder.append(column); } } @@ -270,11 +265,6 @@ void SqliteSqlBuilder::AppendExpr(std::string &builder, std::vector builder += ' '; } -bool SqliteSqlBuilder::IsNotEmptyString(const std::string &str) -{ - return (!str.empty()); -} - std::string SqliteSqlBuilder::BuildQueryString( const AbsRdbPredicates &predicates, const std::vector &columns) { @@ -297,172 +287,5 @@ std::string SqliteSqlBuilder::BuildCountString(const AbsRdbPredicates &predicate std::string tableName = predicates.GetTableName(); return "SELECT COUNT(*) FROM " + tableName + BuildSqlStringFromPredicates(predicates); } - - -std::string SqliteSqlBuilder::PredicatesNormalize(const std::string &source, int &errorCode) -{ - errorCode = 0; - if (StringUtils::IsEmpty(source)) { - LOG_ERROR("Input param is empty."); - return ""; - } - - auto index = source.rfind("(*"); - if (index != std::string::npos) { - return source; - } - - index = source.rfind("."); - if (index == std::string::npos) { - return StringUtils::SurroundWithQuote(source, "`"); - } - - auto fIndex = source.find("."); - if (index != fIndex) { - LOG_ERROR("More than one '.' exists in source"); - errorCode = -1; - return ""; - } - - std::string retStr1 = StringUtils::SurroundWithQuote(source.substr(0, index), "`"); - std::string source2 = StringUtils::Trim(source.substr(index + 1)); - std::string retStr2 = source2 == "*" ? source2 : StringUtils::SurroundWithQuote(source2, "`"); - - return retStr1 + "." + retStr2; -} - -std::string SqliteSqlBuilder::NormalizeWords(const std::string &source, int &errorCode) -{ - DISTRIBUTED_DATA_HITRACE("SqliteSqlBuilder::NormalizeWords"); - errorCode = 0; - if (StringUtils::IsEmpty(source)) { - return ""; - } - std::string strTrimed = StringUtils::Trim(source); - std::string obj = "*"; - if (obj == strTrimed) { - return "*"; - } - std::regex pattern("^(" + patternWords_ + ")$"); - std::smatch result; - auto wordMatcher = std::regex_match(strTrimed, result, pattern); - if (!wordMatcher) { - return ""; - } - std::string words = StringUtils::IsEmpty(result[2]) ? result[3] : result[2]; - return StringUtils::SurroundWithQuote(words, "`"); -} - -std::string SqliteSqlBuilder::NormalizeTableColumn(const std::string &source, int &errorCode) -{ - DISTRIBUTED_DATA_HITRACE("SqliteSqlBuilder::NormalizeTableColumn"); - errorCode = 0; - if (StringUtils::IsEmpty(source)) { - return ""; - } - std::string strTrimed = StringUtils::Trim(source); - std::regex pattern_table("^(" + patternWords_ + ")[.](" + patternWords_ + "|\\*)$"); - std::smatch result; - bool columnMatcher = std::regex_match(strTrimed, result, pattern_table); - if (!columnMatcher) { - return ""; - } - std::string firstName = StringUtils::IsEmpty(result[2]) ? StringUtils::Trim(result[3]) - : StringUtils::Trim(result[2]); - std::string lastName = StringUtils::IsEmpty(result[5]) ? StringUtils::Trim(result[6]) - : StringUtils::Trim(result[5]); - lastName = StringUtils::IsEmpty(lastName) ? StringUtils::Trim(result[4]) : lastName; - std::string aresult(StringUtils::SurroundWithQuote(firstName, "`")); - std::string obj = "*"; - if (obj == lastName) { - aresult.append(".").append(lastName); - } else { - aresult.append(".").append(StringUtils::SurroundWithQuote(lastName, "`")); - } - return aresult; -} - -std::string SqliteSqlBuilder::NormalizeMethodPattern(const std::string &source, int &errorCode) -{ - DISTRIBUTED_DATA_HITRACE("SqliteSqlBuilder::NormalizeMethodPattern"); - errorCode = 0; - if (StringUtils::IsEmpty(source)) { - return ""; - } - std::string strTrimed = StringUtils::Trim(source); - std::regex pattern("^(\\w+)(\\()(.*)(\\))$"); - std::smatch result; - bool columnMatcher = std::regex_match(strTrimed, result, pattern); - if (!columnMatcher) { - return StringUtils::SurroundWithQuote(strTrimed, "`"); - } - std::string methodName = StringUtils::Trim(result[1]); - std::string methodParams = StringUtils::Trim(result[3]); - if (StringUtils::IsEmpty(methodParams)) { - return methodName.append("()"); - } - return methodName.append("(").append(methodParams).append(")"); -} - -std::string SqliteSqlBuilder::Normalize(const std::string &words, int &errorCode) -{ - DISTRIBUTED_DATA_HITRACE("SqliteSqlBuilder::Normalize"); - errorCode = 0; - std::string aresult = NormalizeWords(words, errorCode); - if (!StringUtils::IsEmpty(aresult)) { - return aresult; - } - aresult = NormalizeTableColumn(words, errorCode); - if (!StringUtils::IsEmpty(aresult)) { - return aresult; - } - aresult = NormalizeMethodPattern(words, errorCode); - if (!StringUtils::IsEmpty(aresult)) { - return aresult; - } - return ""; -} - -std::string SqliteSqlBuilder::NormalizeAlias(const std::string &source, int &errorCode) -{ - errorCode = 0; - if (StringUtils::IsEmpty(source)) { - return ""; - } - std::string strTrimed = StringUtils::Trim(source); - std::regex pattern("^(.+)\\s+(AS|as)\\s+(" + patternWords_ + ")$"); - std::smatch result; - bool columnMatcher = std::regex_match(strTrimed, result, pattern); - if (!columnMatcher) { - return Normalize(strTrimed, errorCode); - } - std::string words = StringUtils::Trim(result[1]); - if (StringUtils::IsEmpty(words)) { - errorCode = E_SQLITE_SQL_BUILDER_NORMALIZE_FAIL; - return ""; - } - std::string aresult = Normalize(words, errorCode); - if (StringUtils::IsEmpty(aresult)) { - LOG_DEBUG("NormalizeAlias words no match Normalize %{public}s", words.c_str()); - return ""; - } - - std::string alias = result[3]; - if (StringUtils::IsEmpty(alias)) { - LOG_DEBUG("NormalizeAlias alias is empty"); - return aresult; - } - std::string obj = aresult.substr(aresult.length() - 1, 1); - if ("*" == obj) { - errorCode = E_SQLITE_SQL_BUILDER_NORMALIZE_FAIL; - return ""; - } - std::string presult = NormalizeWords(alias, errorCode); - if (!StringUtils::IsEmpty(presult)) { - LOG_DEBUG("NormalizeAlias alias no match NormalizeWords %{public}s", alias.c_str()); - aresult.append(" as ").append(presult); - } - return aresult; -} } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/step_result_set.cpp b/relational_store/frameworks/native/rdb/src/step_result_set.cpp index 97cfff20..28211692 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -54,7 +54,6 @@ StepResultSet::~StepResultSet() int StepResultSet::GetAllColumnNames(std::vector &columnNames) { - std::shared_lock lock(mutex_); if (!columnNames_.empty()) { columnNames = columnNames_; return E_OK; @@ -95,7 +94,6 @@ int StepResultSet::GetAllColumnNames(std::vector &columnNames) int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) { - std::shared_lock lock(mutex_); if (isClosed) { LOG_ERROR("resultSet closed"); return E_STEP_RESULT_CLOSED; @@ -162,7 +160,7 @@ int StepResultSet::GoToRow(int position) } // If the moved position is less than zero, reset the result and return an error if (position < 0) { - LOG_ERROR("position %{public}d.", position); + LOG_DEBUG("position %{public}d.", position); Reset(); return E_ERROR; } @@ -189,7 +187,6 @@ int StepResultSet::GoToRow(int position) */ int StepResultSet::GoToNextRow() { - std::shared_lock lock(mutex_); if (isClosed) { LOG_ERROR("resultSet closed"); return E_STEP_RESULT_CLOSED; @@ -224,17 +221,18 @@ int StepResultSet::GoToNextRow() isAfterLast = true; rowCount = rowPos_ + 1; FinishStep(); + rowPos_ = rowCount; return E_STEP_RESULT_IS_AFTER_LAST; } else { LOG_ERROR("step ret is %{public}d", errCode); FinishStep(); + rowPos_ = rowCount; return SQLiteError::ErrNo(errCode); } } int StepResultSet::Close() { - std::unique_lock lock(mutex_); if (isClosed) { return E_OK; } @@ -340,7 +338,6 @@ int StepResultSet::IsAtFirstRow(bool &result) const int StepResultSet::GetBlob(int columnIndex, std::vector &blob) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -354,7 +351,6 @@ int StepResultSet::GetBlob(int columnIndex, std::vector &blob) int StepResultSet::GetString(int columnIndex, std::string &value) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -373,7 +369,6 @@ int StepResultSet::GetString(int columnIndex, std::string &value) int StepResultSet::GetInt(int columnIndex, int &value) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -393,7 +388,6 @@ int StepResultSet::GetInt(int columnIndex, int &value) int StepResultSet::GetLong(int columnIndex, int64_t &value) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -410,7 +404,6 @@ int StepResultSet::GetLong(int columnIndex, int64_t &value) int StepResultSet::GetDouble(int columnIndex, double &value) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -442,7 +435,6 @@ int StepResultSet::Get(int32_t col, ValueObject &value) int StepResultSet::GetModifyTime(std::string &modifyTime) { - std::shared_lock lock(mutex_); if (isClosed) { return E_STEP_RESULT_CLOSED; } @@ -460,7 +452,6 @@ int StepResultSet::GetModifyTime(std::string &modifyTime) int StepResultSet::GetSize(int columnIndex, size_t &size) { - std::shared_lock lock(mutex_); if (rowPos_ == INIT_POS) { size = 0; return E_STEP_RESULT_QUERY_NOT_EXECUTED; @@ -486,7 +477,6 @@ int StepResultSet::IsColumnNull(int columnIndex, bool &isNull) */ bool StepResultSet::IsClosed() const { - std::shared_lock lock(mutex_); return isClosed; } @@ -504,7 +494,6 @@ int StepResultSet::GetValue(int32_t col, T &value) std::pair StepResultSet::GetValueObject(int32_t col, size_t index) { - std::shared_lock lock(mutex_); if (isClosed) { return { E_STEP_RESULT_CLOSED, ValueObject() }; } @@ -521,4 +510,4 @@ std::pair StepResultSet::GetValueObject(int32_t col, size_t in return { ret, std::move(value) }; } } // namespace NativeRdb -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/string_utils.cpp b/relational_store/frameworks/native/rdb/src/string_utils.cpp index 11c3f6d1..52242138 100644 --- a/relational_store/frameworks/native/rdb/src/string_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/string_utils.cpp @@ -17,23 +17,22 @@ namespace OHOS { namespace NativeRdb { -std::string StringUtils::SurroundWithQuote(std::string value, std::string quote) +std::string StringUtils::SurroundWithQuote(const std::string &value, const std::string "e) { if (value.empty()) { return value; } - std::string str = quote + value + quote; - return str; + return quote + value + quote; } // Join array members as parameters of a function call. -std::string StringUtils::SurroundWithFunction(std::string function, std::string separator, - std::vector array) +std::string StringUtils::SurroundWithFunction(const std::string &function, const std::string &separator, + const std::vector &array) { std::string builder(function); builder += "("; bool isFirst = true; - for (auto text : array) { + for (auto &text : array) { if (!isFirst) { builder = builder + " " + separator + " "; } else { diff --git a/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp b/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp index e74ab240..82439413 100644 --- a/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp +++ b/relational_store/frameworks/native/rdb_bms_adaptor/src/data_share_profile_info.cpp @@ -27,6 +27,8 @@ namespace OHOS::RdbBMSAdapter { using namespace OHOS::Rdb; +std::mutex DataShareProfileInfo::infosMutex_; + constexpr const char *DATA_SHARE_PROFILE_META = "ohos.extension.dataShare"; constexpr const char *PROFILE_FILE_PREFIX = "$profile:"; const size_t PROFILE_PREFIX_LEN = strlen(PROFILE_FILE_PREFIX); @@ -123,6 +125,7 @@ std::vector DataShareProfileInfo::GetResProfileByMetadata( std::shared_ptr DataShareProfileInfo::InitResMgr(const std::string &resourcePath) { + std::lock_guard lock(infosMutex_); static std::shared_ptr resMgr(CreateResourceManager()); if (resMgr == nullptr) { return nullptr; diff --git a/relational_store/interfaces/inner_api/dataability/include/data_ability_predicates.h b/relational_store/interfaces/inner_api/dataability/include/data_ability_predicates.h index 6633504f..aeb0553b 100644 --- a/relational_store/interfaces/inner_api/dataability/include/data_ability_predicates.h +++ b/relational_store/interfaces/inner_api/dataability/include/data_ability_predicates.h @@ -36,7 +36,7 @@ public: /** * @brief Constructor. */ - API_EXPORT explicit DataAbilityPredicates(std::string rawSelection); + API_EXPORT explicit DataAbilityPredicates(const std::string &rawSelection); /** * @brief Constructor. diff --git a/relational_store/interfaces/inner_api/rdb/BUILD.gn b/relational_store/interfaces/inner_api/rdb/BUILD.gn index cae6ea39..9dd419b1 100644 --- a/relational_store/interfaces/inner_api/rdb/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb/BUILD.gn @@ -38,7 +38,7 @@ base_sources = [ "${relational_store_native_path}/rdb/src/values_bucket.cpp", ] -if (is_ohos) { +if (is_ohos && !build_ohos_sdk) { config("native_rdb_config") { visibility = [ ":*" ] @@ -92,10 +92,7 @@ if (is_ohos) { deps = base_deps - deps += [ - "${kvstore_path}/libs/distributeddb:distributeddb", - "//third_party/sqlite:sqlite", - ] + deps += [ "//third_party/sqlite:sqlite" ] ldflags = [ "-Wl,--exclude-libs,ALL" ] cflags_cc = [ "-fvisibility=hidden" ] @@ -121,12 +118,15 @@ if (is_ohos) { ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", "hitrace:hitrace_meter", "huks:libhukssdk", "ipc:ipc_core", + "kv_store:distributeddb", "samgr:samgr_proxy", ] @@ -142,10 +142,7 @@ if (is_ohos) { deps = base_deps - deps += [ - "${kvstore_path}/libs/distributeddb:distributeddb", - "//third_party/sqlite:sqlite", - ] + deps += [ "//third_party/sqlite:sqlite" ] ldflags = [ "-Wl,--exclude-libs,ALL" ] sources += [ @@ -170,12 +167,15 @@ if (is_ohos) { ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", "hitrace:hitrace_meter", "huks:libhukssdk", "ipc:ipc_core", + "kv_store:distributeddb", "samgr:samgr_proxy", ] @@ -378,11 +378,11 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "${distributedfile_path}/mod_securitylabel", "${relational_store_common_path}/include", "${relational_store_innerapi_path}/rdb/mock/include", "${relational_store_native_path}/rdb/mock/include", "${relational_store_innerapi_path}/rdb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", "${relational_store_native_path}/rdb/include", ] @@ -418,14 +418,17 @@ if (is_ohos) { defines = [ "ANDROID_PLATFORM" ] part_name = "relational_store" + sources = base_sources configs = [ ":native_rdb_config" ] deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + "${relational_store_native_path}/rdb/src/security_policy.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_android", @@ -442,6 +445,7 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "${distributedfile_path}/mod_securitylabel", "${relational_store_common_path}/include", "${relational_store_innerapi_path}/rdb/mock/include", "${relational_store_native_path}/rdb/mock/include", @@ -489,8 +493,10 @@ if (is_ohos) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + "${relational_store_native_path}/rdb/src/security_policy.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_ios", @@ -502,4 +508,6 @@ if (is_ohos) { public_configs = [ ":native_rdb_public_config" ] subsystem_name = "distributeddatamgr" } +} else { + not_needed([ "base_sources" ]) } diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_predicates.h b/relational_store/interfaces/inner_api/rdb/include/abs_predicates.h index 828a2764..f977eecd 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_predicates.h @@ -34,11 +34,11 @@ public: }; API_EXPORT std::string GetWhereClause() const; - API_EXPORT void SetWhereClause(std::string whereClause); + API_EXPORT void SetWhereClause(const std::string &whereClause); API_EXPORT std::vector GetWhereArgs() const; - API_EXPORT void SetWhereArgs(std::vector whereArgs); + API_EXPORT void SetWhereArgs(const std::vector &whereArgs); API_EXPORT std::string GetOrder() const; - API_EXPORT void SetOrder(std::string order); + API_EXPORT void SetOrder(const std::string &order); API_EXPORT int GetLimit() const; API_EXPORT int GetOffset() const; API_EXPORT bool IsDistinct() const; @@ -49,34 +49,35 @@ public: public: API_EXPORT virtual void Clear(); - API_EXPORT virtual AbsPredicates *EqualTo(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *NotEqualTo(std::string field, std::string value); + API_EXPORT virtual AbsPredicates *EqualTo(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *NotEqualTo(const std::string &field, const std::string &value); API_EXPORT virtual AbsPredicates *BeginWrap(); API_EXPORT virtual AbsPredicates *EndWrap(); API_EXPORT virtual AbsPredicates *Or(); API_EXPORT virtual AbsPredicates *And(); - API_EXPORT virtual AbsPredicates *Contains(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *BeginsWith(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *EndsWith(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *IsNull(std::string field); - API_EXPORT virtual AbsPredicates *IsNotNull(std::string field); - API_EXPORT virtual AbsPredicates *Like(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *Glob(std::string field, std::string value); + API_EXPORT virtual AbsPredicates *Contains(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *BeginsWith(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *EndsWith(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *IsNull(const std::string &field); + API_EXPORT virtual AbsPredicates *IsNotNull(const std::string &field); + API_EXPORT virtual AbsPredicates *Like(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *Glob(const std::string &field, const std::string &value); API_EXPORT virtual AbsPredicates *Between(std::string field, std::string low, std::string high); API_EXPORT virtual AbsPredicates *NotBetween(std::string field, std::string low, std::string high); - API_EXPORT virtual AbsPredicates *GreaterThan(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *LessThan(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *GreaterThanOrEqualTo(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *LessThanOrEqualTo(std::string field, std::string value); - API_EXPORT virtual AbsPredicates *OrderByAsc(std::string field); - API_EXPORT virtual AbsPredicates *OrderByDesc(std::string field); + API_EXPORT virtual AbsPredicates *GreaterThan(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *LessThan(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *GreaterThanOrEqualTo(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *LessThanOrEqualTo(const std::string &field, const std::string &value); + API_EXPORT virtual AbsPredicates *OrderByAsc(const std::string &field); + API_EXPORT virtual AbsPredicates *OrderByDesc(const std::string &field); API_EXPORT virtual AbsPredicates *Distinct(); - API_EXPORT virtual AbsPredicates *Limit(int value); - API_EXPORT virtual AbsPredicates *Offset(int rowOffset); - API_EXPORT virtual AbsPredicates *GroupBy(std::vector fields); - API_EXPORT virtual AbsPredicates *IndexedBy(std::string indexName); - API_EXPORT virtual AbsPredicates *In(std::string field, std::vector values); - API_EXPORT virtual AbsPredicates *NotIn(std::string field, std::vector values); + API_EXPORT virtual AbsPredicates *Limit(int limit); + API_EXPORT virtual AbsPredicates *Limit(int offset, int limit); + API_EXPORT virtual AbsPredicates *Offset(int offset); + API_EXPORT virtual AbsPredicates *GroupBy(const std::vector &fields); + API_EXPORT virtual AbsPredicates *IndexedBy(const std::string &indexName); + API_EXPORT virtual AbsPredicates *In(const std::string &field, const std::vector &values); + API_EXPORT virtual AbsPredicates *NotIn(const std::string &field, const std::vector &values); private: std::string whereClause; @@ -91,12 +92,12 @@ private: bool isSorted; void Initial(); - bool CheckParameter(std::string methodName, std::string field, std::initializer_list args) const; - std::string RemoveQuotes(std::string source) const; - std::string Normalized(std::string source); + bool CheckParameter( + const std::string &methodName, const std::string &field, const std::initializer_list &args) const; + std::string RemoveQuotes(const std::string &source) const; void CheckIsNeedAnd(); - void AppendWhereClauseWithInOrNotIn(std::string methodName, std::string field, - std::vector replaceValues); + void AppendWhereClauseWithInOrNotIn(const std::string &methodName, const std::string &field, + const std::vector &replaceValues); }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h index febd0299..f1e513c6 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h @@ -33,7 +33,7 @@ public: * * @param tableName Indicates the table name of the database. */ - API_EXPORT explicit AbsRdbPredicates(std::string tableName); + API_EXPORT explicit AbsRdbPredicates(const std::string &tableName); /** * @brief Constructor. @@ -42,7 +42,7 @@ public: * * @param tableName Indicates the table name of the database. */ - API_EXPORT explicit AbsRdbPredicates(std::vector tables); + API_EXPORT explicit AbsRdbPredicates(const std::vector &tables); /** * @brief Destructor. @@ -94,7 +94,7 @@ public: * * @return Returns the self. */ - API_EXPORT AbsRdbPredicates* EqualTo(std::string field, std::string value) override; + API_EXPORT AbsRdbPredicates* EqualTo(const std::string &field, const std::string &value) override; /** * @brief Restricts the value of the field to be not equal to the specified value to the remote AbsRdbPredicates. @@ -106,7 +106,7 @@ public: * * @return Returns the self. */ - API_EXPORT AbsRdbPredicates* NotEqualTo(std::string field, std::string value) override; + API_EXPORT AbsRdbPredicates* NotEqualTo(const std::string &field, const std::string &value) override; /** * @brief Adds an and condition to the remote AbsRdbPredicates. @@ -128,7 +128,7 @@ public: * * @param field Indicates the column name for sorting the return list. */ - API_EXPORT AbsRdbPredicates* OrderByAsc(std::string field) override; + API_EXPORT AbsRdbPredicates* OrderByAsc(const std::string &field) override; /** * @brief Restricts the descending order of the return list. When there are several orders, @@ -136,7 +136,7 @@ public: * * @param field Indicates the column name for sorting the return list. */ - API_EXPORT AbsRdbPredicates* OrderByDesc(std::string field) override; + API_EXPORT AbsRdbPredicates* OrderByDesc(const std::string &field) override; /** * @brief Get predicates of remote device. @@ -157,7 +157,7 @@ public: * @brief Sets the join types in the predicates. The value can be {@code INNER JOIN}, {@code LEFT OUTER JOIN}, * and {@code CROSS JOIN}. */ - API_EXPORT virtual void SetJoinTypes(const std::vector joinTypes); + API_EXPORT virtual void SetJoinTypes(const std::vector &joinTypes); /** * @brief Obtains the database table names of the joins in the predicates. @@ -167,7 +167,7 @@ public: /** * @brief Sets the database table names of the joins in the predicates. */ - API_EXPORT virtual void SetJoinTableNames(const std::vector joinTableNames); + API_EXPORT virtual void SetJoinTableNames(const std::vector &joinTableNames); /** * @brief Obtains the join conditions in the predicates. @@ -177,7 +177,7 @@ public: /** * @brief Sets the join conditions required in the predicates. */ - API_EXPORT virtual void SetJoinConditions(const std::vector joinConditions); + API_EXPORT virtual void SetJoinConditions(const std::vector &joinConditions); /** * @brief Obtains the join clause in the predicates. diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h index b962d25e..73dc022f 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h @@ -17,7 +17,6 @@ #define NATIVE_RDB_ABS_SHARED_RESULT_SET_H #include -#include #include #include #include @@ -123,7 +122,7 @@ public: * @return Returns the value of the specified column as a double. */ API_EXPORT int GetAsset(int32_t col, ValueObject::Asset &value) override; - + /** * @brief Obtains the value of the specified column in the current row as assets. * @@ -184,7 +183,7 @@ public: /** * @brief Obtains a block from the {@link SharedResultSet}. */ - API_EXPORT AppDataFwk::SharedBlock *GetBlock() const override; + API_EXPORT AppDataFwk::SharedBlock *GetBlock() override; /** * @brief Called when the position of the result set changes. @@ -211,15 +210,15 @@ public: /** * @brief Checks whether an {@code AbsSharedResultSet} object contains shared blocks. */ - API_EXPORT bool HasBlock() const; + API_EXPORT bool HasBlock(); protected: int CheckState(int columnIndex); void ClearBlock(); + void InitBlock(); void ClosedBlock(); virtual void Finalize(); - std::shared_mutex mutex_; private: // The default position of the cursor static const int INIT_POS = -1; @@ -227,7 +226,8 @@ private: friend class ISharedResultSetStub; friend class ISharedResultSetProxy; // The SharedBlock owned by this AbsSharedResultSet - AppDataFwk::SharedBlock *sharedBlock_ = nullptr; + AppDataFwk::SharedBlock *sharedBlock_ = nullptr; + std::string sharedBlockName_ = "defaultSharedBlockName"; }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h index 51aa2c50..c12f906c 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h @@ -283,6 +283,16 @@ static constexpr int E_CON_OVER_LIMIT = (E_BASE + 48); * @brief The error when the sharedblock unit is null. */ static constexpr int E_NULL_OBJECT = (E_BASE + 49); + +/** +* @brief Failed to get DataObsMgrClient. +*/ +static constexpr int E_GET_DATAOBSMGRCLIENT_FAIL = (E_BASE + 50); + +/** + * @brief The error when the type of the distributed table does not match. + */ +static constexpr int E_TYPE_MISMATCH = (E_BASE + 51); } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/include/rdb_predicates.h index e5273e17..67be56ec 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_predicates.h @@ -32,7 +32,7 @@ public: * * @param tableName Indicates the table name of the database. */ - API_EXPORT explicit RdbPredicates(std::string tableName); + API_EXPORT explicit RdbPredicates(const std::string &tableName); /** * @brief Destructor. @@ -47,33 +47,43 @@ public: /** * @brief Adds a {@code cross join} condition to a SQL statement. */ - API_EXPORT RdbPredicates *CrossJoin(std::string tableName); + API_EXPORT RdbPredicates *CrossJoin(const std::string &tableName); /** * @brief Adds an {@code inner join} condition to a SQL statement. */ - API_EXPORT RdbPredicates *InnerJoin(std::string tableName); + API_EXPORT RdbPredicates *InnerJoin(const std::string &tableName); /** * @brief Adds a {@code left outer join} condition to a SQL statement. */ - API_EXPORT RdbPredicates *LeftOuterJoin(std::string tableName); + API_EXPORT RdbPredicates *LeftOuterJoin(const std::string &tableName); /** * @brief Adds a {@code using} condition to the predicate. * This method is similar to {@code using} of the SQL statement. */ - API_EXPORT RdbPredicates *Using(std::vector fields); + API_EXPORT RdbPredicates *Using(const std::vector &fields); /** * @brief Adds an {@code on} condition to the predicate. */ - API_EXPORT RdbPredicates *On(std::vector clauses); + API_EXPORT RdbPredicates *On(const std::vector &clauses); + + /** + * @brief Get statement with predicates. + */ + API_EXPORT std::string GetStatement(); + + /** + * @brief Get arguments with predicates. + */ + API_EXPORT std::vector GetBindArgs(); private: std::string ProcessJoins() const; std::string GetGrammar(int type) const; - RdbPredicates *Join(int join, std::string tableName); + RdbPredicates *Join(int join, const std::string &tableName); }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h index 891da413..528fbf53 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h @@ -61,4 +61,4 @@ public: }; } } // namespace OHOS::DistributedRdb -#endif +#endif \ No newline at end of file diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h index fe99849a..08b1e29c 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h @@ -113,7 +113,8 @@ public: * @param initialValues Indicates the row of data {@link ValuesBucket} to be inserted into the table. * @param conflictResolution Indicates the {@link ConflictResolution} to insert data into the table. */ - virtual int InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const ValuesBucket &initialValues, + virtual int InsertWithConflictResolution(int64_t &outRowId, const std::string &table, + const ValuesBucket &initialValues, ConflictResolution conflictResolution = ConflictResolution::ON_CONFLICT_NONE) = 0; /** @@ -410,6 +411,11 @@ public: */ virtual int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) = 0; + /** + * @brief When SubscribeMode is LOCAL or LOCALSHARED, this function needs to be called to trigger callback. + */ + virtual int Notify(const std::string &event) = 0; + /** * @brief Drop the specified devices Data. * diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h index cbe11566..a564f285 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h @@ -442,6 +442,16 @@ public: */ API_EXPORT std::map GetScalarFunctions() const; + /** + * @brief Sets the module name for the object. + */ + void SetDataGroupId(const std::string &DataGroupId); + + /** + * @brief Obtains the module name in this {@code StoreConfig} object. + */ + std::string GetDataGroupId() const; + /** * @brief Overload the line number operator. */ @@ -508,6 +518,7 @@ private: int pageSize; int readConSize_ = 4; std::string encryptAlgo; + std::string dataGroupId_; std::map customScalarFunctions; }; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h index 44ecbdfe..2771aab7 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h @@ -81,6 +81,16 @@ enum Progress { SYNC_FINISH, }; +enum ProgressCode { + SUCCESS = 0, + UNKNOWN_ERROR, + NETWORK_ERROR, + CLOUD_DISABLED, + LOCKED_BY_OTHERS, + RECORD_LIMIT_EXCEEDED, + NO_SPACE_FOR_ASSET, +}; + struct Statistic { uint32_t total; uint32_t success; @@ -156,11 +166,14 @@ enum SubscribeMode { REMOTE, CLOUD, CLOUD_DETAIL, + LOCAL, + LOCAL_SHARED, SUBSCRIBE_MODE_MAX }; struct SubscribeOption { SubscribeMode mode; + std::string event; }; struct Origin { @@ -193,6 +206,7 @@ public: CHG_TYPE_DELETE, CHG_TYPE_BUTT }; + virtual ~RdbStoreObserver() {}; using PrimaryKey = std::variant; using ChangeInfo = std::map[CHG_TYPE_BUTT]>; using PrimaryFields = std::map; @@ -201,6 +215,7 @@ public: { OnChange(origin.id); }; + virtual void OnChange() {}; }; struct DropOption { diff --git a/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h b/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h index bd4c414e..b47d3aa2 100644 --- a/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h @@ -43,7 +43,7 @@ public: /** * @brief Obtains a block from the {@link SharedResultSet}. */ - virtual AppDataFwk::SharedBlock *GetBlock() const = 0; + virtual AppDataFwk::SharedBlock *GetBlock() = 0; /** * @brief Adds the data of a {@code SharedResultSet} to a {@link SharedBlock}. diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/abs_rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/mock/include/abs_rdb_predicates.h index 4b69fd88..68885f55 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/abs_rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/abs_rdb_predicates.h @@ -22,8 +22,8 @@ namespace OHOS::NativeRdb { class AbsRdbPredicates : public AbsPredicates { public: - explicit AbsRdbPredicates(std::string tableName); - explicit AbsRdbPredicates(std::vector tables); + explicit AbsRdbPredicates(const std::string &tableName); + explicit AbsRdbPredicates(const std::vector &tables); ~AbsRdbPredicates() override {} void Clear() override; @@ -34,11 +34,11 @@ public: virtual void InitialParam(); virtual std::vector GetJoinTypes(); - virtual void SetJoinTypes(const std::vector joinTypes); + virtual void SetJoinTypes(const std::vector &joinTypes); virtual std::vector GetJoinTableNames(); - virtual void SetJoinTableNames(const std::vector joinTableNames); + virtual void SetJoinTableNames(const std::vector &joinTableNames); virtual std::vector GetJoinConditions(); - virtual void SetJoinConditions(const std::vector joinConditions); + virtual void SetJoinConditions(const std::vector &joinConditions); virtual std::string GetJoinClause() const; virtual int GetJoinCount() const; virtual void SetJoinCount(int joinCount); diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_predicates.h index 3ed1ebe3..4c6d4aaf 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_predicates.h @@ -23,20 +23,22 @@ namespace OHOS { namespace NativeRdb { class RdbPredicates : public AbsRdbPredicates { public: - explicit RdbPredicates(std::string tableName); + explicit RdbPredicates(const std::string &tableName); ~RdbPredicates() override {} std::string GetJoinClause() const override; - RdbPredicates *CrossJoin(std::string tableName); - RdbPredicates *InnerJoin(std::string tableName); - RdbPredicates *LeftOuterJoin(std::string tableName); - RdbPredicates *Using(std::vector fields); - RdbPredicates *On(std::vector clauses); + RdbPredicates *CrossJoin(const std::string &tableName); + RdbPredicates *InnerJoin(const std::string &tableName); + RdbPredicates *LeftOuterJoin(const std::string &tableName); + RdbPredicates *Using(const std::vector &fields); + RdbPredicates *On(const std::vector &clauses); + std::string GetStatement(); + std::vector GetBindArgs(); private: std::string ProcessJoins() const; std::string GetGrammar(int type) const; - RdbPredicates *Join(int join, std::string tableName); + RdbPredicates *Join(int join, const std::string &tableName); }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h index 71d0bf32..08fee1c0 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h @@ -25,10 +25,15 @@ #include "value_object.h" #include "values_bucket.h" #include "rdb_common.h" +#include "rdb_types.h" namespace OHOS::NativeRdb { class RdbStore { public: + using RdbStoreObserver = DistributedRdb::RdbStoreObserver; + using PRIKey = RdbStoreObserver::PrimaryKey; + using Date = DistributedRdb::Date; + virtual ~RdbStore() {} #ifdef WINDOWS_PLATFORM virtual void Clear(); diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h index 1e4dc8d9..dfa86e7c 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h @@ -60,7 +60,7 @@ enum class SecurityLevel : int32_t { static constexpr int DB_PAGE_SIZE = 4096; /* default page size : 4k */ static constexpr int DB_JOURNAL_SIZE = 1024 * 1024; /* default file size : 1M */ -static constexpr char DB_DEFAULT_JOURNAL_MODE[] = "delete"; +static constexpr char DB_DEFAULT_JOURNAL_MODE[] = "WAL"; static constexpr char DB_DEFAULT_ENCRYPT_ALGO[] = "sha256"; using ScalarFunction = std::function&)>; @@ -74,7 +74,8 @@ struct ScalarFunctionInfo { class RdbStoreConfig { public: RdbStoreConfig(const std::string &path, StorageMode storageMode = StorageMode::MODE_DISK, bool readOnly = false, - const std::vector &encryptKey = std::vector(), const std::string &journalMode = "delete", + const std::vector &encryptKey = std::vector(), + const std::string &journalMode = DB_DEFAULT_JOURNAL_MODE, const std::string &syncMode = "", const std::string &databaseFileType = "", SecurityLevel securityLevel = SecurityLevel::LAST, bool isCreateNecessary = true, bool autoCheck = false, int journalSize = 1048576, int pageSize = 4096, @@ -135,6 +136,8 @@ public: int GetReadConSize() const; void SetReadConSize(int readConSize); void SetScalarFunction(const std::string &functionName, int argc, ScalarFunction function); + void SetDataGroupId(const std::string &dataGroupId); + std::string GetDataGroupId() const; std::map GetScalarFunctions() const; bool operator==(const RdbStoreConfig &config) const @@ -195,6 +198,7 @@ private: int pageSize; int readConSize_ = 4; std::string encryptAlgo; + std::string dataGroupId_; std::map customScalarFunctions; }; diff --git a/relational_store/interfaces/inner_api/rdb_bms_adapter/include/data_share_profile_info.h b/relational_store/interfaces/inner_api/rdb_bms_adapter/include/data_share_profile_info.h index 5a2e8520..90cc2f30 100644 --- a/relational_store/interfaces/inner_api/rdb_bms_adapter/include/data_share_profile_info.h +++ b/relational_store/interfaces/inner_api/rdb_bms_adapter/include/data_share_profile_info.h @@ -22,6 +22,8 @@ #include "resource_manager.h" #include "serializable.h" +#include + namespace OHOS::RdbBMSAdapter { using namespace OHOS::Global::Resource; struct API_EXPORT Config final : public Serializable { @@ -57,6 +59,7 @@ private: bool isCompressed); static std::string ReadProfile(const std::string &resPath); static bool IsFileExisted(const std::string &filePath); + static std::mutex infosMutex_; }; } // namespace OHOS::RdbBMSAdapter #endif // RDB_BMS_ADAPTER_PROFILE_INFO_H diff --git a/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn b/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn index 086f5229..06d9b359 100644 --- a/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn @@ -43,13 +43,13 @@ ohos_shared_library("rdb_data_ability_adapter") { subsystem_name = "distributeddatamgr" part_name = "relational_store" - deps = [ "${relational_store_innerapi_path}/rdb:native_rdb" ] - - external_deps = [ - "c_utils:utils", - "relational_store:native_dataability", + deps = [ + "${relational_store_innerapi_path}/dataability:native_dataability", + "${relational_store_innerapi_path}/rdb:native_rdb", ] + external_deps = [ "c_utils:utils" ] + public_configs = [ ":rdb_data_ability_adapter_public_config" ] innerapi_tags = [ "platformsdk" ] diff --git a/relational_store/interfaces/ndk/BUILD.gn b/relational_store/interfaces/ndk/BUILD.gn index 4326da78..51d6323e 100644 --- a/relational_store/interfaces/ndk/BUILD.gn +++ b/relational_store/interfaces/ndk/BUILD.gn @@ -42,31 +42,3 @@ ohos_ndk_library("libnative_rdb_ndk") { "$ndk_headers_out_dir/database/rdb/relational_store_error_code.h", ] } - -ohos_shared_library("native_rdb_ndk") { - include_dirs = [ - "include", - "${relational_store_common_path}/include", - "${relational_store_native_path}/rdb/include", - ] - sources = [ - "src/relational_cursor.cpp", - "src/relational_predicates.cpp", - "src/relational_store.cpp", - "src/relational_value_object.cpp", - "src/relational_values_bucket.cpp", - ] - - defines = [ "API_EXPORT=__attribute__((visibility (\"default\")))" ] - - deps = [ "${relational_store_innerapi_path}/rdb:native_rdb" ] - - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - ] - - relative_install_dir = "ndk" - part_name = "relational_store" - subsystem_name = "distributeddatamgr" -} diff --git a/relational_store/interfaces/ndk/include/oh_cursor.h b/relational_store/interfaces/ndk/include/oh_cursor.h index 60cf8876..165da158 100644 --- a/relational_store/interfaces/ndk/include/oh_cursor.h +++ b/relational_store/interfaces/ndk/include/oh_cursor.h @@ -237,14 +237,14 @@ typedef struct OH_Cursor { int (*isNull)(OH_Cursor *cursor, int32_t columnIndex, bool *isNull); /** - * @brief Function pointer. Closes the result set, releasing all of its resources and making it completely invalid. + * @brief Function pointer. Destroy the result set, releasing all of its resources and making it completely invalid. * * @param cursor Represents a pointer to an {@link OH_Cursor} instance. * @return Returns the status code of the execution. * @see OH_Cursor. * @since 10 */ - int (*close)(OH_Cursor *cursor); + int (*destroy)(OH_Cursor *cursor); } OH_Cursor; #ifdef __cplusplus diff --git a/relational_store/interfaces/ndk/include/oh_predicates.h b/relational_store/interfaces/ndk/include/oh_predicates.h index c69fea34..28808e30 100644 --- a/relational_store/interfaces/ndk/include/oh_predicates.h +++ b/relational_store/interfaces/ndk/include/oh_predicates.h @@ -393,7 +393,7 @@ typedef struct OH_Predicates { * @see OH_Predicates. * @since 10 */ - int (*destroyPredicates)(OH_Predicates *predicates); + int (*destroy)(OH_Predicates *predicates); } OH_Predicates; #ifdef __cplusplus diff --git a/relational_store/interfaces/ndk/include/oh_value_object.h b/relational_store/interfaces/ndk/include/oh_value_object.h index 9e739f57..f8ddd1a6 100644 --- a/relational_store/interfaces/ndk/include/oh_value_object.h +++ b/relational_store/interfaces/ndk/include/oh_value_object.h @@ -110,7 +110,7 @@ typedef struct OH_VObject { * @see OH_VObject. * @since 10 */ - int (*destroyValueObject)(OH_VObject *valueObject); + int (*destroy)(OH_VObject *valueObject); } OH_VObject; #ifdef __cplusplus diff --git a/relational_store/interfaces/ndk/include/oh_values_bucket.h b/relational_store/interfaces/ndk/include/oh_values_bucket.h index 4594851f..e966956b 100644 --- a/relational_store/interfaces/ndk/include/oh_values_bucket.h +++ b/relational_store/interfaces/ndk/include/oh_values_bucket.h @@ -136,7 +136,7 @@ typedef struct OH_VBucket { * @see OH_VBucket. * @since 10 */ - int (*destroyValuesBucket)(OH_VBucket *bucket); + int (*destroy)(OH_VBucket *bucket); } OH_VBucket; #ifdef __cplusplus diff --git a/relational_store/interfaces/ndk/include/relational_store.h b/relational_store/interfaces/ndk/include/relational_store.h index a9e00b67..7b009ec3 100644 --- a/relational_store/interfaces/ndk/include/relational_store.h +++ b/relational_store/interfaces/ndk/include/relational_store.h @@ -53,27 +53,19 @@ extern "C" { */ typedef enum OH_Rdb_SecurityLevel { /** - * @brief S1: means the db is low level security. - * - * There are some low impact, when the data is leaked. + * @brief Low-level security. Data leaks have a minor impact. */ S1 = 1, /** - * @brief S2: means the db is middle level security. - * - * There are some major impact, when the data is leaked. + * @brief Medium-level security. Data leaks have a major impact. */ S2, /** - * @brief S3: means the db is high level security - * - * There are some severity impact, when the data is leaked. + * @brief High-level security. Data leaks have a severe impact. */ S3, /** - * @brief S4: means the db is critical level security - * - * There are some critical impact, when the data is leaked. + * @brief Critical-level security. Data leaks have a critical impact. */ S4 } OH_Rdb_SecurityLevel; @@ -83,20 +75,38 @@ typedef enum OH_Rdb_SecurityLevel { * * @since 10 */ +#pragma pack(1) typedef struct { /** - * Indicates the path of the database. + * Indicates the size of the {@link OH_Rdb_Config}. It is mandatory. */ - const char *path; + int selfSize; /** - * Indicates whether the database is encrypt. + * Indicates the directory of the database. + */ + const char *dataBaseDir; + /** + * Indicates the name of the database. + */ + const char *storeName; + /** + * Indicates the bundle name of the application. + */ + const char *bundleName; + /** + * Indicates the module name of the application. + */ + const char *moduleName; + /** + * Indicates whether the database is encrypted. */ bool isEncrypt; /** * Indicates the security level {@link OH_Rdb_SecurityLevel} of the database. */ - enum OH_Rdb_SecurityLevel securityLevel; + int securityLevel; } OH_Rdb_Config; +#pragma pack() /** * @brief Define OH_Rdb_Store type. @@ -111,7 +121,7 @@ typedef struct { } OH_Rdb_Store; /** - * @brief Create an {@link OH_VObject} instance. + * @brief Creates an {@link OH_VObject} instance. * * @return If the creation is successful, a pointer to the instance of the @link OH_VObject} structure is returned, * otherwise NULL is returned. @@ -121,7 +131,7 @@ typedef struct { OH_VObject *OH_Rdb_CreateValueObject(); /** - * @brief Create an {@link OH_VBucket} object. + * @brief Creates an {@link OH_VBucket} object. * * @return If the creation is successful, a pointer to the instance of the @link OH_VBucket} structure is returned, * otherwise NULL is returned. @@ -131,7 +141,7 @@ OH_VObject *OH_Rdb_CreateValueObject(); OH_VBucket *OH_Rdb_CreateValuesBucket(); /** - * @brief Create an {@link OH_Predicates} instance. + * @brief Creates an {@link OH_Predicates} instance. * * @param table Indicates the table name. * @return If the creation is successful, a pointer to the instance of the @link OH_Predicates} structure is returned, @@ -172,13 +182,14 @@ int OH_Rdb_CloseStore(OH_Rdb_Store *store); /** * @brief Deletes the database with a specified path. * - * @param path Indicates the database path. + * @param config Represents a pointer to an {@link OH_Rdb_Config} instance. + * Indicates the configuration of the database related to this RDB store. * @return Returns the status code of the execution. Successful execution returns RDB_OK, * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_ErrCode. * @since 10 */ -int OH_Rdb_DeleteStore(const char *path); +int OH_Rdb_DeleteStore(const OH_Rdb_Config *config); /** * @brief Inserts a row of data into the target table. @@ -247,7 +258,7 @@ OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const ch int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql); /** - * @brief Queries data in the database based on SQL statement. + * @brief Queries data in the database based on an SQL statement. * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param sql Indicates the SQL statement to execute. @@ -269,7 +280,7 @@ OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql); int OH_Rdb_BeginTransaction(OH_Rdb_Store *store); /** - * @brief Rollback a transaction in EXCLUSIVE mode. + * @brief Rolls back a transaction in EXCLUSIVE mode. * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. @@ -279,7 +290,7 @@ int OH_Rdb_BeginTransaction(OH_Rdb_Store *store); int OH_Rdb_RollBack(OH_Rdb_Store *store); /** - * @brief Commit a transaction in EXCLUSIVE mode. + * @brief Commits a transaction in EXCLUSIVE mode. * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. @@ -289,7 +300,7 @@ int OH_Rdb_RollBack(OH_Rdb_Store *store); int OH_Rdb_Commit(OH_Rdb_Store *store); /** - * @brief Backups a database on specified path. + * @brief Backs up a database on specified path. * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param databasePath Indicates the database file path. diff --git a/relational_store/interfaces/ndk/src/BUILD.gn b/relational_store/interfaces/ndk/src/BUILD.gn new file mode 100644 index 00000000..a62b56bd --- /dev/null +++ b/relational_store/interfaces/ndk/src/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/distributeddatamgr/relational_store/relational_store.gni") + +ohos_shared_library("native_rdb_ndk") { + include_dirs = [ + "../include", + "${relational_store_common_path}/include", + "${relational_store_native_path}/rdb/include", + ] + sources = [ + "relational_cursor.cpp", + "relational_predicates.cpp", + "relational_predicates_objects.cpp", + "relational_store.cpp", + "relational_values_bucket.cpp", + ] + + defines = [ "API_EXPORT=__attribute__((visibility (\"default\")))" ] + + deps = [ "${relational_store_innerapi_path}/rdb:native_rdb" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + + relative_install_dir = "ndk" + part_name = "relational_store" + subsystem_name = "distributeddatamgr" +} diff --git a/relational_store/interfaces/ndk/src/relational_cursor.cpp b/relational_store/interfaces/ndk/src/relational_cursor.cpp index e8731976..97130b76 100644 --- a/relational_store/interfaces/ndk/src/relational_cursor.cpp +++ b/relational_store/interfaces/ndk/src/relational_cursor.cpp @@ -16,62 +16,55 @@ #include #include #include +#include #include "logger.h" #include "oh_cursor.h" -#include "relational_cursor_impl.h" +#include "relational_cursor.h" #include "relational_store_error_code.h" #include "rdb_errno.h" #include "securec.h" -using namespace OHOS::RdbNdk; - -int Rdb_GetColumnCount(OH_Cursor *cursor, int *count) +namespace OHOS { +namespace RdbNdk { +int RelationalCursor::GetColumnCount(OH_Cursor *cursor, int *count) { - if (cursor == nullptr || count == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, count is NULL ? %{public}d", (cursor == nullptr), - (count == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || count == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - OHOS::RdbNdk::CursorImpl *tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetColumnCount(*count); + return self->resultSet_->GetColumnCount(*count); } -int Rdb_GetColumnType(OH_Cursor *cursor, int32_t columnIndex, OH_ColumnType *columnType) +int RelationalCursor::GetColumnType(OH_Cursor *cursor, int32_t columnIndex, OH_ColumnType *columnType) { - if (cursor == nullptr || columnType == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, columnType is NULL ? %{public}d", - (cursor == nullptr), (columnType == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || columnType == nullptr || columnIndex < 0) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); OHOS::NativeRdb::ColumnType type; - int error = tempCursor->GetResultSet()->GetColumnType(columnIndex, type); + int result = self->resultSet_->GetColumnType(columnIndex, type); *columnType = static_cast(static_cast(type)); - return error; + return result; } -int Rdb_GetColumnIndex(OH_Cursor *cursor, const char *name, int *columnIndex) +int RelationalCursor::GetColumnIndex(OH_Cursor *cursor, const char *name, int *columnIndex) { - if (cursor == nullptr || name == nullptr || columnIndex == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, name is NULL ? %{public}d," - "columnIndex is NULL ? %{public}d", (cursor == nullptr), (name == nullptr), columnIndex == nullptr); + auto self = GetSelf(cursor); + if (self == nullptr || name == nullptr || columnIndex == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetColumnIndex(name, *columnIndex); + return self->resultSet_->GetColumnIndex(name, *columnIndex); } -int Rdb_GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char *name, int length) +int RelationalCursor::GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char *name, int length) { - if (cursor == nullptr || name == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, name is NULL ? %{public}d", (cursor == nullptr), - (name == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || name == nullptr || length <= 0) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); std::string str; - int errCode = tempCursor->GetResultSet()->GetColumnName(columnIndex, str); + int errCode = self->resultSet_->GetColumnName(columnIndex, str); if (errCode != OHOS::NativeRdb::E_OK) { return errCode; } @@ -80,51 +73,44 @@ int Rdb_GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char *name, int le LOG_ERROR("memcpy_s failed, result is %{public}d", result); return OH_Rdb_ErrCode::RDB_ERR; } - return errCode; + return OH_Rdb_ErrCode::RDB_OK; } -int Rdb_GetRowCount(OH_Cursor *cursor, int *count) +int RelationalCursor::GetRowCount(OH_Cursor *cursor, int *count) { - if (cursor == nullptr || count == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, count is NULL ? %{public}d", (cursor == nullptr), - (count == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || count == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetRowCount(*count); + return self->resultSet_->GetRowCount(*count); } -int Rdb_GoToNextRow(OH_Cursor *cursor) +int RelationalCursor::GoToNextRow(OH_Cursor *cursor) { - if (cursor == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d", (cursor == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GoToNextRow(); + return self->resultSet_->GoToNextRow(); } -int Rdb_GetSize(OH_Cursor *cursor, int32_t columnIndex, size_t *size) +int RelationalCursor::GetSize(OH_Cursor *cursor, int32_t columnIndex, size_t *size) { - if (cursor == nullptr || size == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, size is NULL ? %{public}d", (cursor == nullptr), - (size == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || size == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetSize(columnIndex, *size); + return self->resultSet_->GetSize(columnIndex, *size); } -int Rdb_GetText(OH_Cursor *cursor, int32_t columnIndex, char *value, int length) +int RelationalCursor::GetText(OH_Cursor *cursor, int32_t columnIndex, char *value, int length) { - if (cursor == nullptr || value == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, value is NULL ? %{public}d", (cursor == nullptr), - (value == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || value == nullptr || length <= 0) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); std::string str; - int errCode = tempCursor->GetResultSet()->GetString(columnIndex, str); + int errCode = self->resultSet_->GetString(columnIndex, str); if (errCode != OHOS::NativeRdb::E_OK) { return errCode; } @@ -133,41 +119,35 @@ int Rdb_GetText(OH_Cursor *cursor, int32_t columnIndex, char *value, int length) LOG_ERROR("memcpy_s failed, result is %{public}d", result); return OH_Rdb_ErrCode::RDB_ERR; } - return errCode; + return OH_Rdb_ErrCode::RDB_OK; } -int Rdb_GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t *value) +int RelationalCursor::GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t *value) { - if (cursor == nullptr || value == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, value is NULL ? %{public}d", (cursor == nullptr), - (value == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || value == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetLong(columnIndex, *value); + return self->resultSet_->GetLong(columnIndex, *value); } -int Rdb_GetReal(OH_Cursor *cursor, int32_t columnIndex, double *value) +int RelationalCursor::GetReal(OH_Cursor *cursor, int32_t columnIndex, double *value) { - if (cursor == nullptr || value == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, value is NULL ? %{public}d", (cursor == nullptr), - (value == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || value == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - return tempCursor->GetResultSet()->GetDouble(columnIndex, *value); + return self->resultSet_->GetDouble(columnIndex, *value); } -int Rdb_GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length) +int RelationalCursor::GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length) { - if (cursor == nullptr || value == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, value is NULL ? %{public}d", (cursor == nullptr), - (value == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || value == nullptr || length <= 0) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); std::vector vec; - int errCode = tempCursor->GetResultSet()->GetBlob(columnIndex, vec); + int errCode = self->resultSet_->GetBlob(columnIndex, vec); if (errCode != OHOS::NativeRdb::E_OK) { return errCode; } @@ -176,59 +156,59 @@ int Rdb_GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, in LOG_ERROR("memcpy_s failed, result is %{public}d", result); return OH_Rdb_ErrCode::RDB_ERR; } - return errCode; + return OH_Rdb_ErrCode::RDB_OK; } -int Rdb_IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNull) +int RelationalCursor::IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNull) { - if (cursor == nullptr || isNull == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d, value is NULL ? %{public}d", (cursor == nullptr), - (isNull == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr || isNull == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - bool isNULLTemp = false; - auto tempCursor = static_cast(cursor); - int ret = tempCursor->GetResultSet()->IsColumnNull(columnIndex, isNULLTemp); - isNULLTemp == true ? *isNull = true : *isNull = false; - return ret; + return self->resultSet_->IsColumnNull(columnIndex, *isNull); } -int Rdb_Close(OH_Cursor *cursor) +int RelationalCursor::Destroy(OH_Cursor *cursor) { - if (cursor == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { - LOG_ERROR("Parameters set error:cursor is NULL ? %{public}d", (cursor == nullptr)); + auto self = GetSelf(cursor); + if (self == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempCursor = static_cast(cursor); - int errCode = tempCursor->GetResultSet()->Close(); + int errCode = self->resultSet_->Close(); if (errCode != OHOS::NativeRdb::E_OK) { return errCode; } - delete tempCursor; - tempCursor = nullptr; + delete self; return errCode; } -OHOS::RdbNdk::CursorImpl::CursorImpl(std::shared_ptr resultSet) : resultSet_(resultSet) +RelationalCursor::RelationalCursor(std::shared_ptr resultSet) + : resultSet_(std::move(resultSet)) { id = RDB_CURSOR_CID; - getColumnCount = Rdb_GetColumnCount; - getColumnType = Rdb_GetColumnType; - getColumnIndex = Rdb_GetColumnIndex; - getColumnName = Rdb_GetColumnName; - getRowCount = Rdb_GetRowCount; - goToNextRow = Rdb_GoToNextRow; - getSize = Rdb_GetSize; - getText = Rdb_GetText; - getInt64 = Rdb_GetInt64; - getReal = Rdb_GetReal; - getBlob = Rdb_GetBlob; - isNull = Rdb_IsNull; - close = Rdb_Close; + getColumnCount = GetColumnCount; + getColumnType = GetColumnType; + getColumnIndex = GetColumnIndex; + getColumnName = GetColumnName; + getRowCount = GetRowCount; + goToNextRow = GoToNextRow; + getSize = GetSize; + getText = GetText; + getInt64 = GetInt64; + getReal = GetReal; + getBlob = GetBlob; + isNull = IsNull; + destroy = Destroy; } -std::shared_ptr OHOS::RdbNdk::CursorImpl::GetResultSet() +RelationalCursor *RelationalCursor::GetSelf(OH_Cursor *cursor) { - return resultSet_; + if (cursor == nullptr || cursor->id != OHOS::RdbNdk::RDB_CURSOR_CID) { + LOG_ERROR("cursor invalid. is null %{public}d", (cursor == nullptr)); + return nullptr; + } + return static_cast(cursor); } +} // namespace RdbNdk +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/relational_cursor.h b/relational_store/interfaces/ndk/src/relational_cursor.h new file mode 100644 index 00000000..6f556a95 --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_cursor.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_CURSOR_IMPL_H +#define RELATIONAL_CURSOR_IMPL_H + +#include "oh_cursor.h" +#include "result_set.h" +#include + +namespace OHOS { +namespace RdbNdk { +constexpr int RDB_CURSOR_CID = 1234563; // The class id used to uniquely identify the OH_Cursor class. +class RelationalCursor : public OH_Cursor { +public: + explicit RelationalCursor(std::shared_ptr resultSet); +private: + static int GetColumnCount(OH_Cursor *cursor, int *count); + static int GetColumnType(OH_Cursor *cursor, int32_t columnIndex, OH_ColumnType *columnType); + static int GetColumnIndex(OH_Cursor *cursor, const char *name, int *columnIndex); + static int GetColumnName(OH_Cursor *cursor, int32_t columnIndex, char *name, int length); + static int GetRowCount(OH_Cursor *cursor, int *count); + static int GoToNextRow(OH_Cursor *cursor); + static int GetSize(OH_Cursor *cursor, int32_t columnIndex, size_t *size); + static int GetText(OH_Cursor *cursor, int32_t columnIndex, char *value, int length); + static int GetInt64(OH_Cursor *cursor, int32_t columnIndex, int64_t *value); + static int GetReal(OH_Cursor *cursor, int32_t columnIndex, double *value); + static int GetBlob(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length); + static int IsNull(OH_Cursor *cursor, int32_t columnIndex, bool *isNull); + static int Destroy(OH_Cursor *cursor); + static RelationalCursor *GetSelf(OH_Cursor *cursor); + std::shared_ptr resultSet_; +}; +} // namespace RdbNdk +} // namespace OHOS +#endif // RELATIONAL_CURSOR_IMPL_H diff --git a/relational_store/interfaces/ndk/src/relational_predicates.cpp b/relational_store/interfaces/ndk/src/relational_predicates.cpp index 6bab9572..5e33fd58 100644 --- a/relational_store/interfaces/ndk/src/relational_predicates.cpp +++ b/relational_store/interfaces/ndk/src/relational_predicates.cpp @@ -16,382 +16,363 @@ #include "logger.h" #include "oh_predicates.h" #include "relational_store_error_code.h" -#include "relational_predicates_impl.h" -#include "relational_value_object_impl.h" +#include "relational_predicates.h" +#include "relational_predicates_objects.h" #include "sqlite_global_config.h" using namespace OHOS::NativeRdb; -using namespace OHOS::RdbNdk; - -OH_Predicates *Rdb_Predicates_EqualTo(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +namespace OHOS { +namespace RdbNdk { +OH_Predicates *RelationalPredicate::EqualTo(OH_Predicates *predicates, const char *field, OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.EqualTo(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().EqualTo(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_NotEqualTo(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::NotEqualTo(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.NotEqualTo(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().NotEqualTo(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_BeginWrap(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::BeginWrap(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().BeginWrap(); - return predicates; + self->predicates_.BeginWrap(); + return self; } -OH_Predicates *Rdb_Predicates_EndWrap(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::EndWrap(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().EndWrap(); - return predicates; + self->predicates_.EndWrap(); + return self; } -OH_Predicates *Rdb_Predicates_Or(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::Or(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Or(); - return predicates; + self->predicates_.Or(); + return self; } -OH_Predicates *Rdb_Predicates_And(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::And(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().And(); - return predicates; + self->predicates_.And(); + return self; } -OH_Predicates *Rdb_Predicates_IsNull(OH_Predicates *predicates, const char *field) +OH_Predicates *RelationalPredicate::IsNull(OH_Predicates *predicates, const char *field) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().IsNull(field); - return predicates; + self->predicates_.IsNull(field); + return self; } -OH_Predicates *Rdb_Predicates_IsNotNull(OH_Predicates *predicates, const char *field) +OH_Predicates *RelationalPredicate::IsNotNull(OH_Predicates *predicates, const char *field) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().IsNotNull(field); - return predicates; + self->predicates_.IsNotNull(field); + return self; } -OH_Predicates *Rdb_Predicates_Like(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::Like(OH_Predicates *predicates, const char *field, OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.Like(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().Like(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_Between(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::Between(OH_Predicates *predicates, const char *field, OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; } - std::vector tempValue = static_cast(valueObject)->getValue(); + std::vector values = selfObjects->Get(); // The number of arguments required for the between method is 2 - if (tempValue.size() != 2) { - LOG_ERROR("size is %{public}zu", tempValue.size()); - return predicates; + if (values.size() != 2) { + LOG_ERROR("size is %{public}zu", values.size()); + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Between(field, tempValue[0], tempValue[1]); - return predicates; + self->predicates_.Between(field, values[0], values[1]); + return self; } -OH_Predicates *Rdb_Predicates_NotBetween(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::NotBetween(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; } - std::vector tempValue = static_cast(valueObject)->getValue(); + std::vector values = selfObjects->Get(); // The number of arguments required for the between method is 2 - if (tempValue.size() != 2) { - LOG_ERROR("size is %{public}zu", tempValue.size()); - return predicates; + if (values.size() != 2) { + LOG_ERROR("size is %{public}zu", values.size()); + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().NotBetween(field, tempValue[0], tempValue[1]); - return predicates; + self->predicates_.NotBetween(field, values[0], values[1]); + return self; } -OH_Predicates *Rdb_Predicates_GreaterThan(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::GreaterThan(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.GreaterThan(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().GreaterThan(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_LessThan(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::LessThan(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.LessThan(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().LessThan(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_GreaterThanOrEqualTo(OH_Predicates *predicates, const char *field, - OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::GreaterThanOrEqualTo(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().GreaterThanOrEqualTo(field, tempValue[0]); - return predicates; + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.GreaterThanOrEqualTo(field, values[0]); + } + return self; } -OH_Predicates *Rdb_Predicates_LessThanOrEqualTo(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::LessThanOrEqualTo(OH_Predicates *predicates, const char *field, + OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr - || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; + } + std::vector values = selfObjects->Get(); + if (!values.empty()) { + self->predicates_.LessThanOrEqualTo(field, values[0]); } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - tempPredicates->GetPredicates().LessThanOrEqualTo(field, tempValue[0]); - return predicates; + return self; } -OH_Predicates *Rdb_Predicates_OrderBy(OH_Predicates *predicates, const char *field, OH_OrderType type) +OH_Predicates *RelationalPredicate::OrderBy(OH_Predicates *predicates, const char *field, OH_OrderType type) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || field == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); if (type == OH_OrderType::DESC) { - tempPredicates->GetPredicates().OrderByDesc(field); - return predicates; + self->predicates_.OrderByDesc(field); + return self; } - tempPredicates->GetPredicates().OrderByAsc(field); - return predicates; + self->predicates_.OrderByAsc(field); + return self; } -OH_Predicates *Rdb_Predicates_Distinct(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::Distinct(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Distinct(); - return predicates; + self->predicates_.Distinct(); + return self; } -OH_Predicates *Rdb_Predicates_Limit(OH_Predicates *predicates, unsigned int value) +OH_Predicates *RelationalPredicate::Limit(OH_Predicates *predicates, unsigned int value) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Limit(value); - return predicates; + self->predicates_.Limit(value); + return self; } -OH_Predicates *Rdb_Predicates_Offset(OH_Predicates *predicates, unsigned int rowOffset) +OH_Predicates *RelationalPredicate::Offset(OH_Predicates *predicates, unsigned int rowOffset) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Offset(rowOffset); - return predicates; + self->predicates_.Offset(rowOffset); + return self; } -OH_Predicates *Rdb_Predicates_GroupBy(OH_Predicates *predicates, char const *const *fields, int length) +OH_Predicates *RelationalPredicate::GroupBy(OH_Predicates *predicates, char const *const *fields, int length) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || fields == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, fields is NULL ? %{public}d,", - (predicates == nullptr), (fields == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr || fields == nullptr || length == 0) { + return self; } - auto tempPredicates = static_cast(predicates); std::vector vec; vec.reserve(length); for (int i = 0; i < length; i++) { vec.push_back(std::string(fields[i])); } - - tempPredicates->GetPredicates().GroupBy(vec); - return predicates; + self->predicates_.GroupBy(vec); + return self; } -OH_Predicates *Rdb_Predicates_In(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::In(OH_Predicates *predicates, const char *field, OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - if (tempValue.size() > OHOS::NativeRdb::GlobalExpr::SQLITE_MAX_COLUMN) { - return predicates; + std::vector values = selfObjects->Get(); + if (values.size() > OHOS::NativeRdb::GlobalExpr::SQLITE_MAX_COLUMN) { + return self; } - tempPredicates->GetPredicates().In(field, tempValue); - return predicates; + self->predicates_.In(field, values); + return self; } -OH_Predicates *Rdb_Predicates_NotIn(OH_Predicates *predicates, const char *field, OH_VObject *valueObject) +OH_Predicates *RelationalPredicate::NotIn(OH_Predicates *predicates, const char *field, OH_VObject *objects) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID || valueObject == nullptr) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d, field is NULL ? %{public}d," - "valueObject is NULL ? %{public}d", - (predicates == nullptr), (field == nullptr), (valueObject == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + auto selfObjects = RelationalPredicatesObjects::GetSelf(objects); + if (self == nullptr || selfObjects == nullptr || field == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - std::vector tempValue = static_cast(valueObject)->getValue(); - if (tempValue.size() > OHOS::NativeRdb::GlobalExpr::SQLITE_MAX_COLUMN) { - return predicates; + std::vector values = selfObjects->Get(); + if (values.size() > OHOS::NativeRdb::GlobalExpr::SQLITE_MAX_COLUMN) { + return self; } - tempPredicates->GetPredicates().NotIn(field, tempValue); - return predicates; + self->predicates_.NotIn(field, values); + return self; } -OH_Predicates *Rdb_Predicates_Clear(OH_Predicates *predicates) +OH_Predicates *RelationalPredicate::Clear(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); - return nullptr; + auto self = GetSelf(predicates); + if (self == nullptr) { + return self; } - auto tempPredicates = static_cast(predicates); - tempPredicates->GetPredicates().Clear(); - return predicates; + self->predicates_.Clear(); + return self; } -int Rdb_DestroyPredicates(OH_Predicates *predicates) +int RelationalPredicate::Destroy(OH_Predicates *predicates) { - if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { - LOG_ERROR("Parameters set error:predicates is NULL ? %{public}d", (predicates == nullptr)); + auto self = GetSelf(predicates); + if (self == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - delete predicates; - predicates = nullptr; + delete self; return OH_Rdb_ErrCode::RDB_OK; } -OHOS::RdbNdk::PredicateImpl::PredicateImpl(const char *table) : predicates_(table) +RelationalPredicate::RelationalPredicate(const char *table) : predicates_(table) { id = RDB_PREDICATES_CID; - equalTo = Rdb_Predicates_EqualTo; - notEqualTo = Rdb_Predicates_NotEqualTo; - beginWrap = Rdb_Predicates_BeginWrap; - endWrap = Rdb_Predicates_EndWrap; - orOperate = Rdb_Predicates_Or; - andOperate = Rdb_Predicates_And; - isNull = Rdb_Predicates_IsNull; - isNotNull = Rdb_Predicates_IsNotNull; - like = Rdb_Predicates_Like; - between = Rdb_Predicates_Between; - notBetween = Rdb_Predicates_NotBetween; - greaterThan = Rdb_Predicates_GreaterThan; - lessThan = Rdb_Predicates_LessThan; - greaterThanOrEqualTo = Rdb_Predicates_GreaterThanOrEqualTo; - lessThanOrEqualTo = Rdb_Predicates_LessThanOrEqualTo; - orderBy = Rdb_Predicates_OrderBy; - distinct = Rdb_Predicates_Distinct; - limit = Rdb_Predicates_Limit; - offset = Rdb_Predicates_Offset; - groupBy = Rdb_Predicates_GroupBy; - in = Rdb_Predicates_In; - notIn = Rdb_Predicates_NotIn; - clear = Rdb_Predicates_Clear; - destroyPredicates = Rdb_DestroyPredicates; + equalTo = EqualTo; + notEqualTo = NotEqualTo; + beginWrap = BeginWrap; + endWrap = EndWrap; + orOperate = Or; + andOperate = And; + isNull = IsNull; + isNotNull = IsNotNull; + like = Like; + between = Between; + notBetween = NotBetween; + greaterThan = GreaterThan; + lessThan = LessThan; + greaterThanOrEqualTo = GreaterThanOrEqualTo; + lessThanOrEqualTo = LessThanOrEqualTo; + orderBy = OrderBy; + distinct = Distinct; + limit = Limit; + offset = Offset; + groupBy = GroupBy; + in = In; + notIn = NotIn; + clear = Clear; + destroy = Destroy; } -RdbPredicates &OHOS::RdbNdk::PredicateImpl::GetPredicates() +OHOS::NativeRdb::RdbPredicates &RelationalPredicate::Get() { return predicates_; -} \ No newline at end of file +} + +RelationalPredicate* RelationalPredicate::GetSelf(OH_Predicates *predicates) +{ + if (predicates == nullptr || predicates->id != OHOS::RdbNdk::RDB_PREDICATES_CID) { + LOG_ERROR("cursor invalid. is null %{public}d", (predicates == nullptr)); + return nullptr; + } + return static_cast(predicates); +} +} // namespace RdbNdk +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/relational_predicates.h b/relational_store/interfaces/ndk/src/relational_predicates.h new file mode 100644 index 00000000..60555a1a --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_predicates.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_PREDICATES_IMPL_H +#define RELATIONAL_PREDICATES_IMPL_H + +#include "rdb_predicates.h" +#include "oh_predicates.h" + +namespace OHOS { +namespace RdbNdk { +constexpr int RDB_PREDICATES_CID = 1234561; // The class id used to uniquely identify the OH_Predicates class. +class RelationalPredicate : public OH_Predicates { +public: + explicit RelationalPredicate(const char *table); + static RelationalPredicate *GetSelf(OH_Predicates *predicates); + OHOS::NativeRdb::RdbPredicates &Get(); +private: + static OH_Predicates *EqualTo(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *NotEqualTo(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *BeginWrap(OH_Predicates *predicates); + static OH_Predicates *EndWrap(OH_Predicates *predicates); + static OH_Predicates *Or(OH_Predicates *predicates); + static OH_Predicates *And(OH_Predicates *predicates); + static OH_Predicates *IsNull(OH_Predicates *predicates, const char *field); + static OH_Predicates *IsNotNull(OH_Predicates *predicates, const char *field); + static OH_Predicates *Like(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *Between(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *NotBetween(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *GreaterThan(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *LessThan(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + static OH_Predicates *GreaterThanOrEqualTo(OH_Predicates *predicates, const char *field, + OH_VObject *valueObject); + static OH_Predicates *LessThanOrEqualTo(OH_Predicates *predicates, const char *field, + OH_VObject *valueObject); + static OH_Predicates *OrderBy(OH_Predicates *predicates, const char *field, OH_OrderType type); + static OH_Predicates *Distinct(OH_Predicates *predicates); + static OH_Predicates *Limit(OH_Predicates *predicates, unsigned int value); + static OH_Predicates *Offset(OH_Predicates *predicates, unsigned int rowOffset); + static OH_Predicates *GroupBy(OH_Predicates *predicates, char const *const *fields, int length); + static OH_Predicates *In(OH_Predicates *predicates, const char *field, OH_VObject *objects); + static OH_Predicates *NotIn(OH_Predicates *predicates, const char *field, OH_VObject *objects); + static OH_Predicates *Clear(OH_Predicates *predicates); + static int Destroy(OH_Predicates *predicates); + static bool GetObjects(OH_Predicates *predicates, OH_VObject *objects, + std::vector &values); + OHOS::NativeRdb::RdbPredicates predicates_; +}; +} // namespace RdbNdk +} // namespace OHOS +#endif // RELATIONAL_PREDICATES_IMPL_H diff --git a/relational_store/interfaces/ndk/src/relational_predicates_objects.cpp b/relational_store/interfaces/ndk/src/relational_predicates_objects.cpp new file mode 100644 index 00000000..4d3c70b6 --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_predicates_objects.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "logger.h" +#include "oh_value_object.h" +#include "relational_store_error_code.h" +#include "relational_predicates_objects.h" + +namespace OHOS { +namespace RdbNdk { +// The class id used to uniquely identify the OH_VObject class. +constexpr int RDB_PREDICATES_OBJECTS_CID = 1234565; +int RelationalPredicatesObjects::PutInt64(OH_VObject *objects, int64_t *value, uint32_t count) +{ + auto self = GetSelf(objects); + if (self == nullptr || value == nullptr || count == 0) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + self->values_.clear(); + self->values_.reserve(count); + for (uint32_t i = 0; i < count; i++) { + self->values_.push_back(std::to_string(value[i])); + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int RelationalPredicatesObjects::PutDouble(OH_VObject *objects, double *value, uint32_t count) +{ + auto self = GetSelf(objects); + if (self == nullptr || value == nullptr || count == 0) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + self->values_.clear(); + self->values_.reserve(count); + for (uint32_t i = 0; i < count; i++) { + self->values_.push_back(std::to_string(value[i])); + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int RelationalPredicatesObjects::PutText(OH_VObject *objects, const char *value) +{ + auto self = GetSelf(objects); + if (self == nullptr || value == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + self->values_.clear(); + self->values_.push_back(value); + return OH_Rdb_ErrCode::RDB_OK; +} + +int RelationalPredicatesObjects::PutTexts(OH_VObject *objects, const char **value, uint32_t count) +{ + auto self = GetSelf(objects); + if (self == nullptr || value == nullptr || count == 0) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + + self->values_.clear(); + self->values_.reserve(count); + for (uint32_t i = 0; i < count; i++) { + self->values_.push_back(value[i]); + } + return OH_Rdb_ErrCode::RDB_OK; +} + +int RelationalPredicatesObjects::Destroy(OH_VObject *objects) +{ + auto self = GetSelf(objects); + if (self == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + delete self; + return OH_Rdb_ErrCode::RDB_OK; +} + +RelationalPredicatesObjects::RelationalPredicatesObjects() +{ + id = RDB_PREDICATES_OBJECTS_CID; + putInt64 = PutInt64; + putDouble = PutDouble; + putText = PutText; + putTexts = PutTexts; + destroy = Destroy; +} + +RelationalPredicatesObjects *RelationalPredicatesObjects::GetSelf(OH_VObject *objects) +{ + if (objects == nullptr || objects->id != OHOS::RdbNdk::RDB_PREDICATES_OBJECTS_CID) { + LOG_ERROR("predicates objects invalid. is null %{public}d", (objects == nullptr)); + return nullptr; + } + return static_cast(objects); +} + +std::vector &RelationalPredicatesObjects::Get() +{ + return values_; +} +} // namespace RdbNdk +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/relational_predicates_objects.h b/relational_store/interfaces/ndk/src/relational_predicates_objects.h new file mode 100644 index 00000000..cae33636 --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_predicates_objects.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_VALUE_OBJECT_IMPL_H +#define RELATIONAL_VALUE_OBJECT_IMPL_H + +#include "oh_value_object.h" +#include +#include + +namespace OHOS { +namespace RdbNdk { +class RelationalPredicatesObjects : public OH_VObject { +public: + RelationalPredicatesObjects(); + static RelationalPredicatesObjects *GetSelf(OH_VObject *objects); + std::vector &Get(); +private: + static int PutInt64(OH_VObject *objects, int64_t *value, uint32_t count); + static int PutDouble(OH_VObject *objects, double *value, uint32_t count); + static int PutText(OH_VObject *objects, const char *value); + static int PutTexts(OH_VObject *objects, const char **value, uint32_t count); + static int Destroy(OH_VObject *objects); + std::vector values_; +}; +} // namespace RdbNdk +} // namespace OHOS +#endif // RELATIONAL_VALUE_OBJECT_IMPL_H diff --git a/relational_store/interfaces/ndk/src/relational_store.cpp b/relational_store/interfaces/ndk/src/relational_store.cpp index f258c9de..7042094d 100644 --- a/relational_store/interfaces/ndk/src/relational_store.cpp +++ b/relational_store/interfaces/ndk/src/relational_store.cpp @@ -13,30 +13,31 @@ * limitations under the License. */ -#include "relational_store.h" +#include "relational_store_impl.h" #include "logger.h" #include "rdb_errno.h" #include "rdb_helper.h" #include "rdb_predicates.h" -#include "relational_cursor_impl.h" +#include "rdb_sql_utils.h" +#include "relational_cursor.h" #include "relational_store_error_code.h" -#include "relational_predicates_impl.h" +#include "relational_predicates.h" #include "relational_store_impl.h" -#include "relational_value_object_impl.h" -#include "relational_values_bucket_impl.h" +#include "relational_predicates_objects.h" +#include "relational_values_bucket.h" #include "sqlite_global_config.h" using namespace OHOS::RdbNdk; - +constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class. OH_VObject *OH_Rdb_CreateValueObject() { - return new OHOS::RdbNdk::ValueObjectImpl(); + return new (std::nothrow) RelationalPredicatesObjects(); } OH_VBucket *OH_Rdb_CreateValuesBucket() { - return new OHOS::RdbNdk::ValuesBucketImpl(); + return new (std::nothrow) RelationalValuesBucket(); } OH_Predicates *OH_Rdb_CreatePredicates(const char *table) @@ -44,19 +45,14 @@ OH_Predicates *OH_Rdb_CreatePredicates(const char *table) if (table == nullptr) { return nullptr; } - return new OHOS::RdbNdk::PredicateImpl(table); + return new (std::nothrow) RelationalPredicate(table); } -OHOS::RdbNdk::StoreImpl::StoreImpl(std::shared_ptr store) : store_(store) +OHOS::RdbNdk::RelationalStore::RelationalStore(std::shared_ptr store) : store_(store) { id = RDB_STORE_CID; } -std::shared_ptr OHOS::RdbNdk::StoreImpl::GetStore() -{ - return store_; -} - class MainOpenCallback : public OHOS::NativeRdb::RdbOpenCallback { public: int OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override; @@ -73,102 +69,116 @@ int MainOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVers return OHOS::NativeRdb::E_OK; } +RelationalStore *GetRelationalStore(OH_Rdb_Store *store) +{ + if (store == nullptr || store->id != RDB_STORE_CID) { + LOG_ERROR("store is invalid. is null %{public}d", (store == nullptr)); + return nullptr; + } + return static_cast(store); +} + OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) { - if (config == nullptr) { - LOG_ERROR("Parameters set error:config is NULL ? %{public}d", (config == nullptr)); + if (config == nullptr || config->selfSize != sizeof(OH_Rdb_Config)) { + LOG_ERROR("Parameters set error:config is NULL ? %{public}d or config size error %{public}d vs %{public}zu", + (config == nullptr), config->selfSize, sizeof(OH_Rdb_Config)); return nullptr; } - OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(config->path); + + std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, + config->storeName, *errCode); + if (*errCode != 0) { + LOG_ERROR("Get database path failed, ret %{public}d ", *errCode); + return nullptr; + } + OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath); rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel)); rdbStoreConfig.SetEncryptStatus(config->isEncrypt); + if (config->bundleName != nullptr) { + rdbStoreConfig.SetBundleName(config->bundleName); + } + rdbStoreConfig.SetName(config->storeName); MainOpenCallback callback; - std::shared_ptr store = OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode); if (store == nullptr) { + LOG_ERROR("Get RDB Store fail %{public}s", realPath.c_str()); return nullptr; } - return new OHOS::RdbNdk::StoreImpl(store); + return new (std::nothrow) RelationalStore(store); } int OH_Rdb_CloseStore(OH_Rdb_Store *store) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:config is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - delete store; - store = nullptr; + delete rdbStore; return OH_Rdb_ErrCode::RDB_OK; } -int OH_Rdb_DeleteStore(const char *path) +int OH_Rdb_DeleteStore(const OH_Rdb_Config *config) { - if (path == nullptr) { - LOG_ERROR("Parameters set error:path is NULL ? %{public}d", (path == nullptr)); + if (config == nullptr || config->dataBaseDir == nullptr || config->storeName == nullptr) { + LOG_ERROR("Parameters set error:path is NULL ? %{public}d", (config == nullptr)); return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return OHOS::NativeRdb::RdbHelper::DeleteRdbStore(path); + int errCode = OHOS::NativeRdb::E_OK; + std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, + config->storeName, errCode); + if (errCode != OHOS::NativeRdb::E_OK) { + return errCode; + } + return OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath); } int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) { - if (store == nullptr || table == nullptr || valuesBucket == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, table is NULL ? %{public}d," - "valuesBucket is NULL ? %{public}d", - (store == nullptr), (table == nullptr), (valuesBucket == nullptr)); + auto rdbStore = GetRelationalStore(store); + auto bucket = RelationalValuesBucket::GetSelf(valuesBucket); + if (rdbStore == nullptr || table == nullptr || bucket == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } int64_t rowId = -1; - auto tempStore = static_cast(store); - auto valueImpl = static_cast(valuesBucket); - tempStore->GetStore()->Insert(rowId, table, valueImpl->getValuesBucket()); + rdbStore->GetStore()->Insert(rowId, table, bucket->Get()); return rowId >= 0 ? rowId : OH_Rdb_ErrCode::RDB_ERR; } int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valueBucket, OH_Predicates *predicates) { - if (store == nullptr || predicates == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, valueBucket is NULL ? %{public}d," - "predicates is NULL ? %{public}d", - (store == nullptr), (valueBucket == nullptr), (predicates == nullptr)); + auto rdbStore = GetRelationalStore(store); + auto predicate = RelationalPredicate::GetSelf(predicates); + auto bucket = RelationalValuesBucket::GetSelf(valueBucket); + if (rdbStore == nullptr || predicate == nullptr || bucket == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } int updatedRows = -1; - auto tempStore = static_cast(store); - auto tempPredicate = static_cast(predicates); - auto valueImpl = static_cast(valueBucket); - - tempStore->GetStore()->Update(updatedRows, valueImpl->getValuesBucket(), (tempPredicate->GetPredicates())); + rdbStore->GetStore()->Update(updatedRows, bucket->Get(), predicate->Get()); return updatedRows >= 0 ? updatedRows : OH_Rdb_ErrCode::RDB_ERR; } int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates) { - if (store == nullptr || predicates == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, predicates is NULL ? %{public}d", - (store == nullptr), (predicates == nullptr)); + auto rdbStore = GetRelationalStore(store); + auto predicate = RelationalPredicate::GetSelf(predicates); + if (rdbStore == nullptr || predicate == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } int deletedRows = -1; - auto tempStore = static_cast(store); - auto tempPredicate = static_cast(predicates); - tempStore->GetStore()->Delete(deletedRows, (tempPredicate->GetPredicates())); + rdbStore->GetStore()->Delete(deletedRows, predicate->Get()); return deletedRows >= 0 ? deletedRows : OH_Rdb_ErrCode::RDB_ERR; } OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) { - if (store == nullptr || predicates == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID - || length > OHOS::NativeRdb::GlobalExpr::SQLITE_MAX_COLUMN) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, predicates is NULL ? %{public}d," - "length is %{public}d", (store == nullptr), (predicates == nullptr), length); + auto rdbStore = GetRelationalStore(store); + auto predicate = RelationalPredicate::GetSelf(predicates); + if (rdbStore == nullptr || predicate == nullptr) { return nullptr; } - auto tempStore = static_cast(store); - auto tempPredicate = static_cast(predicates); std::vector columns; if (columnNames != nullptr) { columns.reserve(length); @@ -178,110 +188,95 @@ OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const ch } std::shared_ptr resultSet = - tempStore->GetStore()->QueryByStep(tempPredicate->GetPredicates(), columns); + rdbStore->GetStore()->QueryByStep(predicate->Get(), columns); if (resultSet == nullptr) { return nullptr; } - return new OHOS::RdbNdk::CursorImpl(std::move(resultSet)); + return new (std::nothrow) RelationalCursor(std::move(resultSet)); } OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql) { - if (store == nullptr || sql == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, sql is NULL ? %{public}d", (store == nullptr), - (sql == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || sql == nullptr) { return nullptr; } - auto tempStore = static_cast(store); std::shared_ptr resultSet = - tempStore->GetStore()->QuerySql(sql, std::vector{}); + rdbStore->GetStore()->QuerySql(sql, std::vector{}); if (resultSet == nullptr) { return nullptr; } - return new OHOS::RdbNdk::CursorImpl(std::move(resultSet)); + return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet)); } int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) { - if (store == nullptr || sql == nullptr ||store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, sql is NULL ? %{public}d", (store == nullptr), - (sql == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || sql == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->ExecuteSql(sql, std::vector{}); + return rdbStore->GetStore()->ExecuteSql(sql, std::vector{}); } int OH_Rdb_BeginTransaction(OH_Rdb_Store *store) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->BeginTransaction(); + return rdbStore->GetStore()->BeginTransaction(); } int OH_Rdb_RollBack(OH_Rdb_Store *store) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->RollBack(); + return rdbStore->GetStore()->RollBack(); } int OH_Rdb_Commit(OH_Rdb_Store *store) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->Commit(); + return rdbStore->GetStore()->Commit(); } int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath) { - if (store == nullptr || databasePath == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, databasePath is NULL ? %{public}d", - (store == nullptr), (databasePath == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - - return tempStore->GetStore()->Backup(databasePath); + return rdbStore->GetStore()->Backup(databasePath); } int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath) { - if (store == nullptr || databasePath == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d, databasePath is NULL ? %{public}d", - (store == nullptr), (databasePath == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || databasePath == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - - return tempStore->GetStore()->Restore(databasePath); + return rdbStore->GetStore()->Restore(databasePath); } int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr || version == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->GetVersion(*version); + return rdbStore->GetStore()->GetVersion(*version); } int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version) { - if (store == nullptr || store->id != OHOS::RdbNdk::RDB_STORE_CID) { - LOG_ERROR("Parameters set error:store is NULL ? %{public}d", (store == nullptr)); + auto rdbStore = GetRelationalStore(store); + if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - auto tempStore = static_cast(store); - return tempStore->GetStore()->SetVersion(version); + return rdbStore->GetStore()->SetVersion(version); } \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/relational_store_impl.h b/relational_store/interfaces/ndk/src/relational_store_impl.h index 929933ea..4d02f1a3 100644 --- a/relational_store/interfaces/ndk/src/relational_store_impl.h +++ b/relational_store/interfaces/ndk/src/relational_store_impl.h @@ -24,11 +24,13 @@ namespace OHOS { namespace RdbNdk { -constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class. -class StoreImpl : public OH_Rdb_Store { +class RelationalStore : public OH_Rdb_Store { public: - explicit StoreImpl(std::shared_ptr store); - std::shared_ptr GetStore(); + explicit RelationalStore(std::shared_ptr store); + std::shared_ptr GetStore() + { + return store_; + } private: std::shared_ptr store_; diff --git a/relational_store/interfaces/ndk/src/relational_values_bucket.cpp b/relational_store/interfaces/ndk/src/relational_values_bucket.cpp index cc5406eb..a7b351ef 100644 --- a/relational_store/interfaces/ndk/src/relational_values_bucket.cpp +++ b/relational_store/interfaces/ndk/src/relational_values_bucket.cpp @@ -18,56 +18,30 @@ #include "logger.h" #include "oh_values_bucket.h" #include "relational_store_error_code.h" -#include "relational_values_bucket_impl.h" +#include "relational_values_bucket.h" #include "value_object.h" #include "securec.h" -using namespace OHOS::RdbNdk; - -int Rdb_VBucket_PutText(OH_VBucket *bucket, const char *field, const char *value) +namespace OHOS { +namespace RdbNdk { +constexpr int RDB_VBUCKET_CID = 1234562; // The class id used to uniquely identify the OH_Rdb_VBucket class. +int RelationalValuesBucket::PutText(OH_VBucket *bucket, const char *field, const char *value) { - if (bucket == nullptr || field == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; - } - static_cast(bucket)->getValuesBucket().Put( - field, OHOS::NativeRdb::ValueObject(value)); - bucket->capability += 1; - return OH_Rdb_ErrCode::RDB_OK; + return PutValueObject(bucket, field, OHOS::NativeRdb::ValueObject(value)); } -int Rdb_VBucket_PutInt64(OH_VBucket *bucket, const char *field, int64_t value) +int RelationalValuesBucket::PutInt64(OH_VBucket *bucket, const char *field, int64_t value) { - if (bucket == nullptr || field == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d, field is NULL ? %{public}d", (bucket == nullptr), - (field == nullptr)); - return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; - } - static_cast(bucket)->getValuesBucket().Put( - field, OHOS::NativeRdb::ValueObject(value)); - bucket->capability += 1; - return OH_Rdb_ErrCode::RDB_OK; + return PutValueObject(bucket, field, OHOS::NativeRdb::ValueObject(value)); } -int Rdb_VBucket_PutReal(OH_VBucket *bucket, const char *field, double value) +int RelationalValuesBucket::PutReal(OH_VBucket *bucket, const char *field, double value) { - if (bucket == nullptr || field == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d, field is NULL ? %{public}d", (bucket == nullptr), - (field == nullptr)); - return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; - } - static_cast(bucket)->getValuesBucket().Put( - field, OHOS::NativeRdb::ValueObject(value)); - bucket->capability += 1; - return OH_Rdb_ErrCode::RDB_OK; + return PutValueObject(bucket, field, OHOS::NativeRdb::ValueObject(value)); } -int Rdb_VBucket_PutBlob(OH_VBucket *bucket, const char *field, const uint8_t *value, uint32_t size) +int RelationalValuesBucket::PutBlob(OH_VBucket *bucket, const char *field, const uint8_t *value, uint32_t size) { - if (bucket == nullptr || field == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d, field is NULL ? %{public}d", (bucket == nullptr), - (field == nullptr)); - return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; - } std::vector blobValue; if (value != nullptr) { blobValue.reserve(size); @@ -76,61 +50,72 @@ int Rdb_VBucket_PutBlob(OH_VBucket *bucket, const char *field, const uint8_t *va } } - static_cast(bucket)->getValuesBucket().Put( - field, OHOS::NativeRdb::ValueObject(blobValue)); - bucket->capability += 1; - return OH_Rdb_ErrCode::RDB_OK; + return PutValueObject(bucket, field, OHOS::NativeRdb::ValueObject(blobValue)); } -int Rdb_VBucket_PutNull(OH_VBucket *bucket, const char *field) +int RelationalValuesBucket::PutNull(OH_VBucket *bucket, const char *field) { - if (bucket == nullptr || field == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d, field is NULL ? %{public}d", (bucket == nullptr), - (field == nullptr)); - return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; - } - static_cast(bucket)->getValuesBucket().Put(field, OHOS::NativeRdb::ValueObject()); - bucket->capability += 1; - return OH_Rdb_ErrCode::RDB_OK; + return PutValueObject(bucket, field, OHOS::NativeRdb::ValueObject()); } -int Rdb_VBucket_Clear(OH_VBucket *bucket) +int RelationalValuesBucket::Clear(OH_VBucket *bucket) { - if (bucket == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d", (bucket == nullptr)); + auto self = GetSelf(bucket); + if (self == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - static_cast(bucket)->getValuesBucket().Clear(); - bucket->capability = 0; + self->valuesBucket_.Clear(); + self->capability = 0; return OH_Rdb_ErrCode::RDB_OK; } -int Rdb_DestroyValuesBucket(OH_VBucket *bucket) +int RelationalValuesBucket::Destroy(OH_VBucket *bucket) { - if (bucket == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { - LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d", (bucket == nullptr)); + auto self = GetSelf(bucket); + if (self == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - delete bucket; - bucket = nullptr; + + delete self; return OH_Rdb_ErrCode::RDB_OK; } -OHOS::RdbNdk::ValuesBucketImpl::ValuesBucketImpl() +RelationalValuesBucket::RelationalValuesBucket() { id = RDB_VBUCKET_CID; capability = 0; - - putText = Rdb_VBucket_PutText; - putInt64 = Rdb_VBucket_PutInt64; - putReal = Rdb_VBucket_PutReal; - putBlob = Rdb_VBucket_PutBlob; - putNull = Rdb_VBucket_PutNull; - clear = Rdb_VBucket_Clear; - destroyValuesBucket = Rdb_DestroyValuesBucket; + putText = PutText; + putInt64 = PutInt64; + putReal = PutReal; + putBlob = PutBlob; + putNull = PutNull; + clear = Clear; + destroy = Destroy; } -OHOS::NativeRdb::ValuesBucket &OHOS::RdbNdk::ValuesBucketImpl::getValuesBucket() +OHOS::NativeRdb::ValuesBucket &RelationalValuesBucket::Get() { return valuesBucket_; } + +RelationalValuesBucket *RelationalValuesBucket::GetSelf(OH_VBucket *bucket) +{ + if (bucket == nullptr || bucket->id != OHOS::RdbNdk::RDB_VBUCKET_CID) { + LOG_ERROR("Parameters set error:bucket is NULL ? %{public}d", (bucket == nullptr)); + return nullptr; + } + return static_cast(bucket); +} + +int RelationalValuesBucket::PutValueObject(OH_VBucket *bucket, const char *field, OHOS::NativeRdb::ValueObject &&value) +{ + auto self = GetSelf(bucket); + if (self == nullptr || field == nullptr) { + return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; + } + self->valuesBucket_.Put(field, value); + self->capability++; + return OH_Rdb_ErrCode::RDB_OK; +} +} // namespace RdbNdk +} // namespace OHOS diff --git a/relational_store/interfaces/ndk/src/relational_values_bucket.h b/relational_store/interfaces/ndk/src/relational_values_bucket.h new file mode 100644 index 00000000..429773cc --- /dev/null +++ b/relational_store/interfaces/ndk/src/relational_values_bucket.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_VALUES_BUCKET_IMPL_H +#define RELATIONAL_VALUES_BUCKET_IMPL_H + +#include "oh_values_bucket.h" +#include "values_bucket.h" + +namespace OHOS { +namespace RdbNdk { +class RelationalValuesBucket : public OH_VBucket { +public: + RelationalValuesBucket(); + static RelationalValuesBucket *GetSelf(OH_VBucket *bucket); + OHOS::NativeRdb::ValuesBucket &Get(); +private: + static int PutText(OH_VBucket *bucket, const char *field, const char *value); + static int PutInt64(OH_VBucket *bucket, const char *field, int64_t value); + static int PutReal(OH_VBucket *bucket, const char *field, double value); + static int PutBlob(OH_VBucket *bucket, const char *field, const uint8_t *value, uint32_t size); + static int PutNull(OH_VBucket *bucket, const char *field); + static int Clear(OH_VBucket *bucket); + static int Destroy(OH_VBucket *bucket); + static int PutValueObject(OH_VBucket *bucket, const char *field, OHOS::NativeRdb::ValueObject &&value); + OHOS::NativeRdb::ValuesBucket valuesBucket_; +}; +} // namespace RdbNdk +} // namespace OHOS +#endif // RELATIONAL_VALUES_BUCKET_IMPL_H diff --git a/relational_store/relational_store.gni b/relational_store/relational_store.gni index c1f2ddc6..f5718158 100644 --- a/relational_store/relational_store.gni +++ b/relational_store/relational_store.gni @@ -44,4 +44,4 @@ ipc_path = "//foundation/communication/ipc/interfaces/innerkits" kvstore_path = "//foundation/distributeddatamgr/kv_store/frameworks" distributedfile_path = - "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src" + "//foundation/filemanagement/file_api/interfaces/kits/js/src" diff --git a/relational_store/test/js/clouddata/unittest/config.json b/relational_store/test/js/clouddata/unittest/config.json index 41c33891..0683f3ff 100644 --- a/relational_store/test/js/clouddata/unittest/config.json +++ b/relational_store/test/js/clouddata/unittest/config.json @@ -60,7 +60,7 @@ ], "requestPermissions": [ { - "name": "ohos.permission.CLOUDDATA_CONFOG" + "name": "ohos.permission.CLOUDDATA_CONFIG" } ] } diff --git a/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigCallback.js b/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigCallback.js index d3bcf18c..64d7458b 100644 --- a/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigCallback.js +++ b/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigCallback.js @@ -32,10 +32,11 @@ describe('CloudConfigCallbackTest', function () { if (err == undefined) { expect(null).assertFail(); console.info('EnabledCloudInvalidArgsCallbackTest enableCloud success'); - } else { - console.error('EnabledCloudInvalidArgsCallbackTest enableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('EnabledCloudInvalidArgsCallbackTest enableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); done(); }); } catch (e) { @@ -52,18 +53,19 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('EnabledCloudInvalidArgsNumCallbackTest', 0, async function (done) { + it('EnabledCloudInvalidArgsNumCallbackTest', 0, function (done) { console.info('EnabledCloudInvalidArgsNumCallbackTest'); try { let account = "test_id"; - await cloudData.Config.enableCloud(account, function (err) { + cloudData.Config.enableCloud(account, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('EnabledCloudInvalidArgsNumCallbackTest enableCloud success'); - } else { - console.error('EnabledCloudCallbackTest enableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('EnabledCloudCallbackTest enableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); done(); }); } catch (e) { @@ -79,23 +81,25 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('DisableCloudInvalidArgsCallbackTest', 0, async function (done) { + it('DisableCloudInvalidArgsCallbackTest', 0, function (done) { console.info('DisableCloudInvalidArgsCallbackTest'); try { - await cloudData.Config.disableCloud(null, function (err) { + cloudData.Config.disableCloud(null, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('DisableCloudInvalidArgsCallbackTest disableCloud success'); - } else { - console.error('DisableCloudInvalidArgsCallbackTest disableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('DisableCloudInvalidArgsCallbackTest disableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('DisableCloudInvalidArgsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); } - done(); }) /** @@ -104,23 +108,25 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('DisableCloudInvalidArgsNumsCallbackTest', 0, async function (done) { + it('DisableCloudInvalidArgsNumsCallbackTest', 0, function (done) { console.info('DisableCloudInvalidArgsNumsCallbackTest'); try { - await cloudData.Config.disableCloud(function (err) { + cloudData.Config.disableCloud(function (err) { if (err == undefined) { expect(null).assertFail(); console.info('DisableCloudInvalidArgsNumsCallbackTest disableCloud success'); - } else { - console.error('DisableCloudInvalidArgsNumsCallbackTest disableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('DisableCloudInvalidArgsNumsCallbackTest disableCloud fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('DisableCloudInvalidArgsNumsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); } - done(); }) /** @@ -129,25 +135,27 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('ChangeAppCloudInvalidArgsTest', 0, async function (done) { + it('ChangeAppCloudInvalidArgsCallbackTest', 0, function (done) { console.info('ChangeAppCloudInvalidArgsCallbackTest'); try { let account = "test_id"; let bundleName = "test_bundleName"; - await cloudData.Config.changeAppCloudSwitch(account, bundleName, null, function (err) { + cloudData.Config.changeAppCloudSwitch(account, bundleName, null, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('ChangeAppCloudInvalidArgsCallbackTest changeAppCloudSwitch success'); - } else { - console.error('ChangeAppCloudInvalidArgsCallbackTest changeAppCloudSwitch fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('ChangeAppCloudInvalidArgsCallbackTest changeAppCloudSwitch fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('ChangeAppCloudInvalidArgsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); } - done(); }) /** @@ -156,25 +164,27 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('ChangeAppCloudInvalidArgsNumsCallbackTest', 0, async function (done) { + it('ChangeAppCloudInvalidArgsNumsCallbackTest', 0, function (done) { console.info('ChangeAppCloudInvalidArgsNumsCallbackTest'); try { let account = "test_id"; let bundleName = "test_bundleName"; - await cloudData.Config.changeAppCloudSwitch(account, bundleName, function (err) { + cloudData.Config.changeAppCloudSwitch(account, bundleName, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('ChangeAppCloudInvalidArgsNumsCallbackTest changeAppCloudSwitch success'); - } else { - console.error('ChangeAppCloudInvalidArgsNumsCallbackTest changeAppCloudSwitch fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('ChangeAppCloudInvalidArgsNumsCallbackTest changeAppCloudSwitch fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('ChangeAppCloudInvalidArgsNumsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); } - done(); }) /** @@ -183,24 +193,26 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('NotifyChangeInvalidArgsCallbackTest', 0, async function (done) { + it('NotifyChangeInvalidArgsCallbackTest', 0, function (done) { console.info('NotifyChangeInvalidArgsCallbackTest'); try { let account = "test_id"; - await cloudData.Config.notifyDataChange(account, null, function (err) { + cloudData.Config.notifyDataChange(account, null, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('NotifyChangeInvalidArgsCallbackTest notifyDataChange success'); - } else { - console.error('NotifyChangeInvalidArgsCallbackTest notifyDataChange fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('NotifyChangeInvalidArgsCallbackTest notifyDataChange fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('NotifyChangeInvalidArgsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); } - done(); }) /** @@ -209,23 +221,83 @@ describe('CloudConfigCallbackTest', function () { * @tc.type: FUNC * @tc.require: issueNumber */ - it('NotifyChangeInvalidArgsNumsCallbackTest', 0, async function (done) { + it('NotifyChangeInvalidArgsNumsCallbackTest', 0, function (done) { console.info('NotifyChangeInvalidArgsNumsCallbackTest'); try { let account = "test_id"; - await cloudData.Config.notifyDataChange(account, function (err) { + cloudData.Config.notifyDataChange(account, function (err) { if (err == undefined) { expect(null).assertFail(); console.info('NotifyChangeInvalidArgsNumsCallbackTest notifyDataChange success'); - } else { - console.error('NotifyChangeInvalidArgsNumsCallbackTest notifyDataChange fail' + `, error code is ${err.code}, message is ${err.message}`); - expect(null).assertFail(); + done(); + return; } + console.error('NotifyChangeInvalidArgsNumsCallbackTest notifyDataChange fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); }); } catch (e) { console.error('NotifyChangeInvalidArgsNumsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); expect(e.code == 401).assertTrue(); + done(); + } + }) + + /** + * @tc.name ClearInvalidArgsNumsCallbackTest + * @tc.desc Test Js Api Clear which parameters number are less + * @tc.type: FUNC + * @tc.require: issueNumber + */ + it('ClearInvalidArgsNumsCallbackTest', 0, function (done) { + console.info('ClearInvalidArgsNumsCallbackTest'); + try { + let account = "test_id"; + cloudData.Config.clear(account, function (err) { + if (err == undefined) { + expect(null).assertFail(); + console.info('ClearInvalidArgsNumsCallbackTest clear success'); + done(); + return; + } + console.error('ClearInvalidArgsNumsCallbackTest clear fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); + }); + } catch (e) { + console.error('ClearInvalidArgsNumsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); + expect(e.code == 401).assertTrue(); + done(); + } + }) + + /** + * @tc.name ClearInvalidArgsCallbackTest + * @tc.desc Test Js Api Clear which parameters are invalid + * @tc.type: FUNC + * @tc.require: issueNumber + */ + it('ClearInvalidArgsCallbackTest', 0, function (done) { + console.info('ClearInvalidArgsNumsCallbackTest'); + try { + let account = "test_id"; + let bundleName1 = "test_bundleName1"; + let appActions = {[bundleName1]: 3}; + cloudData.Config.clear(account, appActions, function (err) { + if (err == undefined) { + expect(null).assertFail(); + console.info('CleanInvalidArgsCallbackTest clear success'); + done(); + return; + } + console.error('ClearInvalidArgsCallbackTest clear fail' + `, error code is ${err.code}, message is ${err.message}`); + expect(null).assertFail(); + done(); + }); + } catch (e) { + console.error('ClearInvalidArgsCallbackTest fail' + `, error code is ${e.code}, message is ${e.message}`); + expect(e.code == 401).assertTrue(); + done(); } - done(); }) }) diff --git a/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigPromise.js b/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigPromise.js index 8c9e034a..59fa9226 100644 --- a/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigPromise.js +++ b/relational_store/test/js/clouddata/unittest/src/CloudSyncConfigPromise.js @@ -211,4 +211,55 @@ describe('CloudConfigPromiseTest', function () { } done(); }) + + /** + * @tc.name ClearInvalidArgsNumsTest + * @tc.desc Test Js Api Clean which parameters number are less + * @tc.type: FUNC + * @tc.require: issueNumber + */ + it('ClearInvalidArgsNumsTest', 0, async function (done) { + console.info('ClearInvalidArgsNumsTest'); + try { + let account = "test_id"; + await cloudData.Config.clear(account).then(() => { + console.info('ClearInvalidArgsNumsTest success'); + expect(null).assertFail(); + }).catch((error) => { + console.error('ClearInvalidArgsNumsTest clear fail' + `, error code is ${error.code}, message is ${error.message}`); + expect(null).assertFail(); + }); + } catch (e) { + console.error('ClearInvalidArgsNumsTest fail' + `, error code is ${e.code}, message is ${e.message}`); + expect(e.code == 401).assertTrue(); + } + done(); + }) + + /** + * @tc.name ClearInvalidArgsTest + * @tc.desc Test Js Api Clear which parameters are invalid + * @tc.type: FUNC + * @tc.require: issueNumber + */ + it('ClearInvalidArgsTest', 0, async function (done) { + console.info('ClearInvalidArgsTest'); + try { + let account = "test_id"; + let bundleName1 = "test_bundleName1"; + let appActions = {[bundleName1]: 3}; + await cloudData.Config.clear(account, appActions).then(() => { + console.info('ClearInvalidArgsTest success'); + expect(null).assertFail(); + }).catch((error) => { + console.error('ClearInvalidArgsTest clean fail' + `, error code is ${error.code}, message is ${error.message}`); + expect(null).assertFail(); + }); + } catch (e) { + console.error('ClearInvalidArgsTest fail' + `, error code is ${e.code}, message is ${e.message}`); + expect(e.code == 401).assertTrue(); + } + done(); + }) + }) diff --git a/relational_store/test/js/dataability/unittest/config.json b/relational_store/test/js/dataability/unittest/config.json index e1b1bc28..865615d2 100644 --- a/relational_store/test/js/dataability/unittest/config.json +++ b/relational_store/test/js/dataability/unittest/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/relational_store/test/js/rdb/performance/config.json b/relational_store/test/js/rdb/performance/config.json index e1b1bc28..865615d2 100644 --- a/relational_store/test/js/rdb/performance/config.json +++ b/relational_store/test/js/rdb/performance/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/relational_store/test/js/rdb/performance/src/PredicatestPerf.js b/relational_store/test/js/rdb/performance/src/PredicatestPerf.js index 30057c99..d94ebaa2 100644 --- a/relational_store/test/js/rdb/performance/src/PredicatestPerf.js +++ b/relational_store/test/js/rdb/performance/src/PredicatestPerf.js @@ -24,7 +24,7 @@ const BASE_COUNT_FIRST = 200; const BASE_COUNT_SECOND = 10; const BASE_LINE_TABLE = 500; // callback tablet base line const BASE_LINE_PHONE = 1000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('predicatesPerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbHelperCallbackPerf.js b/relational_store/test/js/rdb/performance/src/RdbHelperCallbackPerf.js index 14d02c2a..b2e250f1 100644 --- a/relational_store/test/js/rdb/performance/src/RdbHelperCallbackPerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbHelperCallbackPerf.js @@ -29,7 +29,7 @@ var rdbStore = undefined; const BASE_COUNT = 2000; // loop times const BASE_LINE_TABLE = 2500; // callback tablet base line const BASE_LINE_PHONE = 3000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbHelperCallbackPerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbHelperPromisePerf.js b/relational_store/test/js/rdb/performance/src/RdbHelperPromisePerf.js index 330ffcd2..6e53ee4f 100644 --- a/relational_store/test/js/rdb/performance/src/RdbHelperPromisePerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbHelperPromisePerf.js @@ -29,7 +29,7 @@ var rdbStore = undefined; const BASE_COUNT = 2000; // loop times const BASE_LINE_TABLE = 2500; // callback tablet base line const BASE_LINE_PHONE = 3000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbHelperPromisePerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbStoreCallbackPerf.js b/relational_store/test/js/rdb/performance/src/RdbStoreCallbackPerf.js index 52b39810..c9d4baeb 100644 --- a/relational_store/test/js/rdb/performance/src/RdbStoreCallbackPerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbStoreCallbackPerf.js @@ -32,7 +32,7 @@ const BASE_COUNT = 1000; // loop times const INSERT_BASE_COUNT = 300; const BASE_LINE_TABLE = 1800; // callback tablet base line const BASE_LINE_PHONE = 7000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbStoreCallbackPerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbStoreOthersCallbackPerf.js b/relational_store/test/js/rdb/performance/src/RdbStoreOthersCallbackPerf.js index 03ced635..5af7e211 100644 --- a/relational_store/test/js/rdb/performance/src/RdbStoreOthersCallbackPerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbStoreOthersCallbackPerf.js @@ -32,7 +32,7 @@ const BASE_COUNT = 1000; // loop times const SPECIAL_BASE_COUNT = 300; const BASE_LINE_TABLE = 1800; // callback tablet base line const BASE_LINE_PHONE = 15000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbStoreOthersCallbackPerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbStorePromisePerf.js b/relational_store/test/js/rdb/performance/src/RdbStorePromisePerf.js index 0034a9a8..31441729 100644 --- a/relational_store/test/js/rdb/performance/src/RdbStorePromisePerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbStorePromisePerf.js @@ -31,7 +31,7 @@ var rdbStore = undefined; const BASE_COUNT = 1000; // loop times const BASE_LINE_TABLE = 1800; // callback tablet base line const BASE_LINE_PHONE = 3000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbStorePromisePerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/performance/src/RdbStoreSyncPerf.js b/relational_store/test/js/rdb/performance/src/RdbStoreSyncPerf.js index df364d0c..6e01807b 100644 --- a/relational_store/test/js/rdb/performance/src/RdbStoreSyncPerf.js +++ b/relational_store/test/js/rdb/performance/src/RdbStoreSyncPerf.js @@ -31,7 +31,7 @@ var rdbStore = undefined; const BASE_COUNT = 1000; // loop times const BASE_LINE_TABLE = 2500; // callback tablet base line const BASE_LINE_PHONE = 3000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('rdbStoreSyncPerf', function () { diff --git a/relational_store/test/js/rdb/performance/src/ResultSetPerf.js b/relational_store/test/js/rdb/performance/src/ResultSetPerf.js index 797d1604..a29d8fe3 100644 --- a/relational_store/test/js/rdb/performance/src/ResultSetPerf.js +++ b/relational_store/test/js/rdb/performance/src/ResultSetPerf.js @@ -32,7 +32,7 @@ const BASE_COUNT = 2000; // loop times const SPECIAL_BASE_COUNT = 12000; const BASE_LINE_TABLE = 500; // callback tablet base line const BASE_LINE_PHONE = 1000; // callback phone base line -const BASE_LINE = (deviceInfo.deviceType == "tablet") ? BASE_LINE_TABLE : BASE_LINE_PHONE; +const BASE_LINE = (deviceInfo.deviceType == "tablet" || deviceType == "2in1") ? BASE_LINE_TABLE : BASE_LINE_PHONE; describe('resultSetPerf', function () { beforeAll(async function () { diff --git a/relational_store/test/js/rdb/unittest/config.json b/relational_store/test/js/rdb/unittest/config.json index e1b1bc28..865615d2 100644 --- a/relational_store/test/js/rdb/unittest/config.json +++ b/relational_store/test/js/rdb/unittest/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/relational_store/test/js/relationalstore/performance/config.json b/relational_store/test/js/relationalstore/performance/config.json index e1b1bc28..865615d2 100644 --- a/relational_store/test/js/relationalstore/performance/config.json +++ b/relational_store/test/js/relationalstore/performance/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/relational_store/test/js/relationalstore/unittest/config.json b/relational_store/test/js/relationalstore/unittest/config.json index e1b1bc28..865615d2 100644 --- a/relational_store/test/js/relationalstore/unittest/config.json +++ b/relational_store/test/js/relationalstore/unittest/config.json @@ -17,6 +17,7 @@ "name": ".MyApplication", "deviceType": [ "tablet", + "2in1", "default", "phone" ], diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreAssetResultSetJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreAssetResultSetJsunit.test.js index e30ef45c..f940ce76 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreAssetResultSetJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreAssetResultSetJsunit.test.js @@ -665,8 +665,8 @@ describe('rdbAssetResultSetTest', function () { expect("name4").assertEqual(asset.name); expect("uri4").assertEqual(asset.uri); expect("createTime4").assertEqual(asset.createTime); - expect("modifyTime4").assertEqual(asset.modifyTime); - expect("size4").assertEqual(asset.size); + expect("").assertEqual(asset.modifyTime); + expect("").assertEqual(asset.size); expect("path4").assertEqual(asset.path); expect(data_relationalStore.AssetStatus.ASSET_DELETE).assertEqual(asset.status); } catch (e) { diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js new file mode 100644 index 00000000..2cb589c7 --- /dev/null +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloudSync.test.js @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import relationalStore from '@ohos.data.relationalStore'; +import ability_featureAbility from '@ohos.ability.featureAbility' + +const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" +const STORE_NAME = "cloud_sync_rdb.db" +var rdbStore = undefined; +var context = ability_featureAbility.getContext() + +describe('rdbStoreCloudSyncTest', function () { + beforeAll(async function (done) { + console.info(TAG + 'beforeAll') + const config = { + "name": STORE_NAME, + securityLevel: relationalStore.SecurityLevel.S1, + } + try { + rdbStore = await relationalStore.getRdbStore(context, config); + console.log(TAG + "create rdb store success") + let sql_text = "CREATE TABLE IF NOT EXISTS cloud_text (" + + "data TEXT, " + + "recycled BOOLEAN, " + + "recycledTime INTEGER, " + + "uuid TEXT PRIMARY KEY)"; + let sql_int = "CREATE TABLE IF NOT EXISTS cloud_int (" + + "data TEXT, " + + "recycled BOOLEAN, " + + "recycledTime INTEGER, " + + "uuid INTEGER PRIMARY KEY)"; + let sql_integer = "CREATE TABLE IF NOT EXISTS cloud_integer (" + + "data TEXT, " + + "recycled BOOLEAN, " + + "recycledTime INTEGER, " + + "uuid INTEGER PRIMARY KEY)"; + try { + await rdbStore.executeSql(sql_text, null); + await rdbStore.executeSql(sql_int, null); + await rdbStore.executeSql(sql_integer, null); + console.log(TAG + "create table cloud_text cloud_int cloud_integer success"); + } catch (err) { + console.log(TAG + "create table cloud_text cloud_int cloud_integer failed"); + expect(null).assertFail(); + } + + let tableArray = ["cloud_text", "cloud_integer"]; + const setConfig = { + autoSync: false, + } + let promise = rdbStore.setDistributedTables( + tableArray, relationalStore.DistributedType.DISTRIBUTED_CLOUD, setConfig); + await promise.then(() => { + console.log(TAG + "set disTable success"); + }).catch((err) => { + console.log(TAG + 'set disTable fail, err: ${err}'); + }) + let vBucketArray1 = new Array(); + for (let i = 0; i < 5; i++) { + let valueBucket = { + "data": "cloud_sync_insert", + "recycled": true, + "recycledTime": 12345, + "uuid": "test_key" + i.toString(), + } + vBucketArray1.push(valueBucket); + } + await rdbStore.batchInsert("cloud_text", vBucketArray1); + let vBucketArray2 = new Array(); + for (let i = 0; i < 5; i++) { + let valueBucket = { + "data": "cloud_sync_insert", + "recycled": true, + "recycledTime": 12345, + "uuid": i, + } + vBucketArray2.push(valueBucket); + } + await rdbStore.batchInsert("cloud_integer", vBucketArray2); + } catch (err) { + console.log(TAG + "create rdb store failed" + `, error code is ${err.code}, message is ${err.message}`) + expect(null).assertFail() + } + done(); + }) + + beforeEach(async function () { + console.info(TAG + 'beforeEach') + }) + + afterEach(async function () { + console.info(TAG + 'afterEach') + }) + + afterAll(async function () { + console.info(TAG + 'afterAll') + rdbStore = null + await rdbStore.deleteRdbStore(context, STORE_NAME); + }) + + console.log(TAG + "*************Unit Test Begin*************"); + + /** + * @tc.name get modify time using wrong primary key type + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0001 + * @tc.desc rdb get modify time using wrong primary key type + */ + it('testRdbStoreCloudSync0001', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0001 start *************"); + try { + let key = new Array(); + let PRIKey = [key, "test_key1", "test_key2"]; + rdbStore.getModifyTime("cloud_text", "uuid", PRIKey, function (err, data) { + console.log(TAG + 'modifyTime:' + JSON.stringify(data)); + }); + } catch (err) { + console.log(TAG + `get modify time, err code is ${err.code}, message is ${err.message}.`); + expect(true).assertTrue(); + done(); + } + console.log(TAG + "************* testRdbStoreCloudSync0001 end *************"); + }) + + /** + * @tc.name get modify time using string primary key type and callback method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0002 + * @tc.desc get modify time using string primary key type and callback method + */ + it('testRdbStoreCloudSync0002', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0002 start *************"); + try { + let PRIKey = ["test_key1", "test_key2"]; + rdbStore.getModifyTime("cloud_text", "uuid", PRIKey, function (err, data) { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0002 end *************"); + }) + + /** + * @tc.name get modify time using string primary key type and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0003 + * @tc.desc get modify time using string primary key type and promise method + */ + it('testRdbStoreCloudSync0003', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0003 start *************"); + try { + let PRIKey = ["test_key1", "test_key2"]; + await rdbStore.getModifyTime("cloud_text", "uuid", PRIKey).then((data) => { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + expect(true).assertTrue(); + done(); + }); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0003 end *************"); + }) + + /** + * @tc.name get modify time using rowid and callback method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0004 + * @tc.desc get modify time using rowid and callback method + */ + it('testRdbStoreCloudSync0004', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0004 start *************"); + try { + let PRIKey = [1, 3, 4]; + rdbStore.getModifyTime("cloud_text", "rowid", PRIKey, function (err, data) { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0004 end *************"); + }) + + /** + * @tc.name get modify time using rowid and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0005 + * @tc.desc get modify time using rowid and promise method + */ + it('testRdbStoreCloudSync0005', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0005 start *************"); + try { + let PRIKey = [2, 4]; + await rdbStore.getModifyTime("cloud_text", "roWId", PRIKey).then((data) => { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + expect(true).assertTrue(); + done(); + }); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0005 end *************"); + }) + + /** + * @tc.name get modify time, but not set distributed table + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0004 + * @tc.desc get modify time, but not set distributed table + */ + it('testRdbStoreCloudSync0006', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0006 start *************"); + try { + for (let i = 0; i < 5; i++) { + let valueBucket = { + "data": "cloud_sync_insert", + "recycled": true, + "recycledTime": 12345, + "uuid": i, + } + let vBucketArray = new Array(); + vBucketArray.push(valueBucket); + await rdbStore.batchInsert("cloud_int", vBucketArray); + } + let PRIKey = [0, 1, 2]; + await rdbStore.getModifyTime("cloud_int", "uuid", PRIKey).then((data) => { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + }) + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + expect(true).assertTrue(); + done(); + } + console.log(TAG + "************* testRdbStoreCloudSync0006 end *************"); + }) + + /** + * @tc.name get modify time using int primary key type and callback method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0007 + * @tc.desc get modify time using int primary key type and callback method + */ + it('testRdbStoreCloudSync0007', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0007 start *************"); + try { + let PRIKey = [1, 2, 4]; + rdbStore.getModifyTime("cloud_integer", "uuid", PRIKey, function (err, data) { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0007 end *************"); + }) + + /** + * @tc.name get modify time using int primary key type and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0008 + * @tc.desc get modify time using int primary key type and promise method + */ + it('testRdbStoreCloudSync0008', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0008 start *************"); + try { + let PRIKey = [2, 4]; + await rdbStore.getModifyTime("cloud_integer", "uuid", PRIKey).then((data) => { + console.log(TAG + `modifyTime:` + JSON.stringify(data)); + expect(true).assertTrue(); + done(); + }); + } catch (err) { + console.log(TAG + `get modify time fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0008 end *************"); + }) + + /** + * @tc.name cloud sync with no table, SyncMode is SYNC_MODE_TIME_FIRST and callback method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0009 + * @tc.desc cloud sync with no table, SyncMode is SYNC_MODE_TIME_FIRST and callback method + */ + it('testRdbStoreCloudSync0009', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0009 start *************"); + try { + rdbStore.cloudSync(relationalStore.SyncMode.SYNC_MODE_TIME_FIRST, function (ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + }, function (err, data) { + console.log(TAG + `cloud sync success:` + err); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0009 end *************"); + }) + + /** + * @tc.name cloud sync with no table, SyncMode is SYNC_MODE_TIME_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0010 + * @tc.desc cloud sync with no table, SyncMode is SYNC_MODE_TIME_FIRST and promise method + */ + it('testRdbStoreCloudSync0010', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0010 start *************"); + try { + function Progess(ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + } + await rdbStore.cloudSync(relationalStore.SyncMode.SYNC_MODE_TIME_FIRST, Progess).then((data) => { + console.log(TAG + `cloud sync success:` + data); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0010 end *************"); + }) + + /** + * @tc.name cloud sync with table, SyncMode is SYNC_MODE_TIME_FIRST and callback method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0011 + * @tc.desc cloud sync with table, SyncMode is SYNC_MODE_TIME_FIRST and callback method + */ + it('testRdbStoreCloudSync0011', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0011 start *************"); + try { + function Progess(ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + } + let tableArray = ["cloud_text"]; + rdbStore.cloudSync(relationalStore.SyncMode.SYNC_MODE_TIME_FIRST, tableArray, Progess, + function (err, data) { + console.log(TAG + `cloud sync success:` + err); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0011 end *************"); + }) + + /** + * @tc.name cloud sync with table, SyncMode is SYNC_MODE_TIME_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0012 + * @tc.desc cloud sync with table, SyncMode is SYNC_MODE_TIME_FIRST and promise method + */ + it('testRdbStoreCloudSync0012', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0012 start *************"); + try { + function Progess(ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + } + let tableArray = ["cloud_text"]; + await rdbStore.cloudSync( + relationalStore.SyncMode.SYNC_MODE_TIME_FIRST, tableArray, Progess).then((data) => { + console.log(TAG + `cloud sync success:` + data); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0012 end *************"); + }) + + /** + * @tc.name cloud sync with table, SyncMode is SYNC_MODE_NATIVE_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0013 + * @tc.desc cloud sync with table, SyncMode is SYNC_MODE_NATIVE_FIRST and promise method + */ + it('testRdbStoreCloudSync0013', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0013 start *************"); + try { + function Progess(ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + } + let tableArray = ["cloud_text"]; + await rdbStore.cloudSync( + relationalStore.SyncMode.SYNC_MODE_NATIVE_FIRST, tableArray, Progess).then((data) => { + console.log(TAG + `cloud sync success:` + data); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0013 end *************"); + }) + + /** + * @tc.name cloud sync with table, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_SYNC_0014 + * @tc.desc cloud sync with table, SyncMode is SYNC_MODE_CLOUD_FIRST and promise method + */ + it('testRdbStoreCloudSync0014', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloudSync0014 start *************"); + try { + function Progess(ProgressDetail) { + console.log(TAG + `Progess:` + JSON.stringify(ProgressDetail)); + } + let tableArray = ["cloud_text"]; + await rdbStore.cloudSync( + relationalStore.SyncMode.SYNC_MODE_CLOUD_FIRST, tableArray, Progess).then((data) => { + console.log(TAG + `cloud sync success:` + data); + }); + expect(true).assertTrue(); + done(); + } catch (err) { + console.log(TAG + `cloud sync fail, err code is ${err.code}, message is ${err.message}.`); + } + console.log(TAG + "************* testRdbStoreCloudSync0014 end *************"); + }) + console.log(TAG + "*************Unit Test End*************"); +}) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreBackupRestoreWithFAContextJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreBackupRestoreWithFAContextJsunit.test.js index 36cea6bd..8d4aa87e 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreBackupRestoreWithFAContextJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreBackupRestoreWithFAContextJsunit.test.js @@ -15,7 +15,7 @@ import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' import data_relationalStore from '@ohos.data.relationalStore' import ability_featureAbility from '@ohos.ability.featureAbility' -import fileio from '@ohos.fileio' +import fileio from '@ohos.file.fs' const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " @@ -128,39 +128,32 @@ describe('rdbStoreBackupRestoreWithFAContextTest', function () { await console.log(TAG + "************* RdbBackupRestoreTest_0010 start *************") // RDB backup function test - let promiseBackup = rdbStore.backup(DATABASE_BACKUP_NAME) - promiseBackup.then(() => { - try { - fileio.accessSync(DATABASE_DIR + DATABASE_BACKUP_NAME) - fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name) - } catch (err) { + try { + let promiseBackup = rdbStore.backup(DATABASE_BACKUP_NAME) + promiseBackup.then(() => { + expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + DATABASE_BACKUP_NAME)) + expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name)) + }).catch((errCode) => { expect(false).assertTrue() - } - }).catch((err) => { + }) + await promiseBackup; + } catch(err) { expect(false).assertTrue() - }) - await promiseBackup + } // RDB restore function test - let promiseRestore = rdbStore.restore(DATABASE_BACKUP_NAME) - promiseRestore.then(() => { - try { - fileio.accessSync(DATABASE_DIR + DATABASE_BACKUP_NAME) - expect(false).assertTrue() - } catch (err) { - expect(true).assertTrue() - } - - try { - fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name) - expect(true).assertTrue() - } catch (err) { + try { + let promiseRestore = rdbStore.restore(DATABASE_BACKUP_NAME) + promiseRestore.then(() => { + expect(true).assertEqual(fileio.accessSync(DATABASE_DIR + STORE_CONFIG.name)) + done() + }).catch((errCode) => { expect(false).assertTrue() - } - }).catch((err) => { + }) + await promiseRestore + } catch(err) { expect(false).assertTrue() - }) - await promiseRestore + } // RDB after restored, data query test let predicates = new data_relationalStore.RdbPredicates("test") @@ -231,12 +224,11 @@ describe('rdbStoreBackupRestoreWithFAContextTest', function () { // RDB restore function test, backup file does not exists try { - fileio.accessSync(DATABASE_DIR + dbName) - expect(false).assertTrue() - } catch { - RestoreTest(dbName) + expect(false).assertEqual(fileio.accessSync(DATABASE_DIR + dbName)) + } catch (errCode) { + expect(13900002).assertEqual(errCode.code) } - + RestoreTest(dbName) done() await console.log(TAG + "************* RdbBackupRestoreTest_0040 end *************") }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js index 45f9e2d7..38332583 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js @@ -162,7 +162,7 @@ describe('rdbStoreInsertTest', function () { "blobType": u8, } try { - let insertPromise = rdbStore.insert(null, valueBucket) + let insertPromise = rdbStore.insert(null, valueBucket) insertPromise.then(async (ret) => { expect(1).assertEqual(ret) console.log(TAG + "insert first done: " + ret) @@ -410,23 +410,34 @@ describe('rdbStoreInsertTest', function () { "salary": 200.5, "blobType": u8, } + + rdbStore.beginTransaction() + const valueBucketInsert = { + "name": "wangwu", + "age": 30, + "salary": 400.5, + "blobType": u8, + } + await rdbStore.insert("test", valueBucketInsert) try { - let insertPromise = rdbStore.insert("test", valueBucket, data_relationalStore.ConflictResolution.ON_CONFLICT_ROLLBACK); - insertPromise.then(async (ret) => { - expect(1).assertEqual(ret) - console.log(TAG + "insert first done: " + ret) - expect(null).assertFail() - }).catch((err) => { - console.log(TAG + "insert with wrong valuebucket and ConflictResolution is ON_CONFLICT_ROLLBACK") - done() - }) - } catch(err) { - console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) - expect("401").assertEqual(err.code) - expect(null).assertFail() + await rdbStore.insert("test", valueBucket, data_relationalStore.ConflictResolution.ON_CONFLICT_ROLLBACK); + expect(null).assertFail();; + } catch (err) { + console.log("catch err: failed, err: code=" + err.code + " message=" + err.message); + expect(14800000).assertEqual(err.code); + rdbStore.rollBack(); } } + { + let predicates = await new data_relationalStore.RdbPredicates("test"); + let resultSet = await rdbStore.query(predicates); + + expect(1).assertEqual(resultSet.rowCount); + resultSet.close(); + done(); + } + console.log(TAG + "************* InsertWithConflictResolution_0002 end *************"); }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js index d990822b..bda40f9e 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js @@ -1992,6 +1992,46 @@ describe('rdbPredicatesTest', function () { console.log(TAG + "************* testLimit0006 end *************"); }) + /** + * @tc.name predicates limit normal test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0176 + * @tc.desc predicates limit normal test + */ + it('testLimit0007', 0, async function (done) { + console.log(TAG + "************* testLimit0007 start *************"); + let predicates = new data_relationalStore.RdbPredicates("AllDataType"); + predicates.limitAs(-1); + let result = await rdbStore.query(predicates); + expect(3).assertEqual(result.rowCount); + predicates.clear(); + + predicates.limitAs(1, 1); + result = await rdbStore.query(predicates); + expect(1).assertEqual(result.rowCount); + predicates.clear(); + + predicates.limitAs(0, -1); + result = await rdbStore.query(predicates); + expect(3).assertEqual(result.rowCount); + predicates.clear(); + + predicates.like("stringValue", "ABCDEFGHIJKLMN") + predicates.orderByAsc("id"); + predicates.limitAs(-1, -1); + result = await rdbStore.query(predicates); + expect(3).assertEqual(result.rowCount); + expect(" WHERE stringValue LIKE ? ORDER BY id ASC LIMIT -1 OFFSET -1").assertEqual(predicates.statement); + expect("ABCDEFGHIJKLMN").assertEqual(predicates.bindArgs[0]); + expect(true).assertEqual(result.goToFirstRow()) + expect(1).assertEqual(result.getLong(0)); + expect(2147483647).assertEqual(result.getLong(1)); + expect(DOUBLE_MAX).assertEqual(result.getDouble(2)); + result.close() + result = null + done(); + console.log(TAG + "************* testLimit0007 end *************"); + }) + /** * @tc.name predicates offset normal test * @tc.number SUB_DDM_AppDataFWK_JSRDB_Predicates_0180 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js index 78212677..709eeb63 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstorePromiseJsunit.test.js @@ -200,5 +200,63 @@ describe('rdbStorePromiseTest', function () { console.log(TAG + "************* testRdbStorePromiseTest0005 end *************") }) + /** + * @tc.name rdb getRdbStore err params + * @tc.number testRdbStorePromiseTest0006 + * @tc.desc rdb getRdbStore with dataGroupId in FA mode + */ + it('testRdbStorePromiseTest0006', 0, async function (done) { + console.log(TAG + "************* testRdbStorePromiseTest0006 start *************") + try { + const STORE_CONFIG = { + name: "dataGroupId.db", + encrypt: false, + securityLevel: data_relationalStore.SecurityLevel.S1, + dataGroupId: "12345678", + } + data_relationalStore.getRdbStore(context, STORE_CONFIG).then((rdbStore) => { + console.log("Get RdbStore successfully.") + expect(false).assertTrue() + }).catch((err) => { + console.info("Get RdbStore failed, err: code=" + err.code + " message=" + err.message) + expect(false).assertTrue() + }) + } catch (err) { + console.info("catch err: Get RdbStore failed, err: code=" + err.code + " message=" + err.message) + expect("14801001").assertEqual(err.code) + done() + } + done() + console.log(TAG + "************* testRdbStorePromiseTest0006 end *************") + }) + + /** + * @tc.name rdb deleteRdbStore use storeConfig + * @tc.number testRdbStorePromiseTest0007 + * @tc.desc rdb deleteRdbStore use storeConfig + */ + it('testRdbStorePromiseTest0007', 0, async function (done) { + console.log(TAG + "************* testRdbStorePromiseTest0007 start *************"); + const STORE_CONFIG = { + name: "dataGroupId.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + } + await data_relationalStore.getRdbStore(context, STORE_CONFIG) + try { + data_relationalStore.deleteRdbStore(context, STORE_CONFIG).then((err) => { + console.log("Delete RdbStore successfully.") + done() + }).catch((err) => { + console.info("Delete RdbStore failed, err: code=" + err.code + " message=" + err.message) + expect(false).assertTrue() + }) + } catch(err) { + console.info("catch err: Delete RdbStore failed, err: code=" + err.code + " message=" + err.message) + expect(false).assertTrue() + } + done() + console.log(TAG + "************* testRdbStorePromiseTest0007 end *************") + }) + console.log(TAG + "*************Unit Test End*************"); -}) \ No newline at end of file +}) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js index e76939e2..c2d1fcd8 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreUpdateJsunit.test.js @@ -583,15 +583,13 @@ describe('rdbStoreUpdateTest', function () { } let predicates = await new data_relationalStore.RdbPredicates("test") await predicates.equalTo("age", "19") - let updatePromise = rdbStore.update(valueBucket, predicates, data_relationalStore.ConflictResolution.ON_CONFLICT_NONE); - updatePromise.then(async (ret) => { - await console.log(TAG + "update done: " + ret); - expect(null).assertFail(); - }).catch((err) => { - console.log(TAG + "update error"); + try { + await rdbStore.update(valueBucket, predicates, data_relationalStore.ConflictResolution.ON_CONFLICT_NONE); expect(null).assertFail(); - }) - done() + } catch(err) { + console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) + expect(14800000).assertEqual(err.code) + } } { @@ -776,15 +774,22 @@ describe('rdbStoreUpdateTest', function () { } let predicates = await new data_relationalStore.RdbPredicates("test") await predicates.equalTo("age", "19") - let updatePromise = rdbStore.update(valueBucket, predicates, data_relationalStore.ConflictResolution.ON_CONFLICT_ROLLBACK); - updatePromise.then(async (ret) => { - expect(null).assertFail(); - await console.log(TAG + "update done: " + ret); - }).catch((err) => { + + rdbStore.beginTransaction() + const valueBucketInsert = { + "name": "wangwu", + "age": 30, + "salary": 400.5, + "blobType": u8, + } + await rdbStore.insert("test", valueBucketInsert) + try { + await rdbStore.update(valueBucket, predicates, data_relationalStore.ConflictResolution.ON_CONFLICT_ROLLBACK); expect(null).assertFail(); - console.log(TAG + "update error"); - }) - done() + } catch (err) { + console.log("catch err: failed, err: code=" + err.code + " message=" + err.message); + expect(14800000).assertEqual(err.code); + } } { diff --git a/relational_store/test/native/dataability/BUILD.gn b/relational_store/test/native/dataability/BUILD.gn index 77b788c2..85ae91a7 100644 --- a/relational_store/test/native/dataability/BUILD.gn +++ b/relational_store/test/native/dataability/BUILD.gn @@ -40,7 +40,10 @@ ohos_unittest("NativeDataAbilityTest") { "relational_store:native_rdb", ] - deps = [ "//third_party/googletest:gtest_main" ] + deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", + "//third_party/googletest:gtest_main", + ] } ############################################################################### diff --git a/relational_store/test/native/rdb/BUILD.gn b/relational_store/test/native/rdb/BUILD.gn index 811f11d0..7b05128f 100644 --- a/relational_store/test/native/rdb/BUILD.gn +++ b/relational_store/test/native/rdb/BUILD.gn @@ -71,6 +71,8 @@ ohos_unittest("NativeRdbTest") { configs = [ ":module_private_config" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "hilog:libhilog", "huks:libhukssdk", diff --git a/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/BUILD.gn b/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/BUILD.gn index 2c8c284d..c443cc79 100644 --- a/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/BUILD.gn +++ b/relational_store/test/native/rdb/distributedtest/rdb_store_impl_test/BUILD.gn @@ -44,14 +44,16 @@ ohos_distributedtest("DistributedTest") { sources += [ "distributed_test.cpp" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", "ipc:ipc_core", - "relational_store:native_rdb", ] deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", "//third_party/googletest:gtest_main", "//third_party/icu/icu4c:shared_icui18n", "//third_party/icu/icu4c:shared_icuuc", @@ -65,14 +67,16 @@ ohos_distributedtest("DistributedTestAgent") { sources = [ "distributed_test_agent.cpp" ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", "ipc:ipc_core", - "relational_store:native_rdb", ] deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", "//third_party/googletest:gtest_main", "//third_party/icu/icu4c:shared_icui18n", "//third_party/icu/icu4c:shared_icuuc", diff --git a/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn b/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn index ab97a101..54346bcb 100644 --- a/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn +++ b/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/BUILD.gn @@ -60,6 +60,8 @@ ohos_fuzztest("RdbImplFuzzTest") { ] external_deps = [ + "ability_base:zuri", + "ability_runtime:dataobs_manager", "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", diff --git a/relational_store/test/native/rdb/fuzztest/rdbstore_fuzzer/rdbstore_fuzzer.cpp b/relational_store/test/native/rdb/fuzztest/rdbstore_fuzzer/rdbstore_fuzzer.cpp index a42303cf..73a29d50 100644 --- a/relational_store/test/native/rdb/fuzztest/rdbstore_fuzzer/rdbstore_fuzzer.cpp +++ b/relational_store/test/native/rdb/fuzztest/rdbstore_fuzzer/rdbstore_fuzzer.cpp @@ -21,22 +21,20 @@ using namespace OHOS; using namespace OHOS::NativeRdb; -namespace OHOS { -/* change value */ -constexpr int ageChange = 2; -constexpr double salaryChange = 100; -constexpr double salaryChanges = 200; +namespace OHOS { class RdbStoreFuzzTest { public: static void SetUpTestCase(void); static void TearDownTestCase(void); + static bool InsertData(std::shared_ptr &store, const uint8_t *data, size_t size); + static const std::string DATABASE_NAME; static std::shared_ptr store_; }; std::shared_ptr RdbStoreFuzzTest::store_ = nullptr; -const std::string RdbStoreFuzzTest::DATABASE_NAME = "/data/test/rdbstore_test.db"; +const std::string RdbStoreFuzzTest::DATABASE_NAME = "/data/test/rdbStoreFuzz.db"; class RdbTestOpenCallback : public RdbOpenCallback { public: @@ -44,11 +42,10 @@ public: int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override; static const std::string CREATE_TABLE_TEST; }; - -const std::string RdbTestOpenCallback::CREATE_TABLE_TEST = std::string("CREATE TABLE IF NOT EXISTS test ") - + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, " - "name TEXT NOT NULL, age INTEGER, salary " - "REAL, blobType BLOB)"); +const std::string RdbTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER, salary REAL, " + "blobType BLOB)"; int RdbTestOpenCallback::OnCreate(RdbStore &store) { @@ -66,98 +63,113 @@ void RdbStoreFuzzTest::SetUpTestCase(void) RdbStoreConfig config(DATABASE_NAME); RdbTestOpenCallback helper; RdbStoreFuzzTest::store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode); + if (store_ == nullptr || errCode != E_OK) { + return; + } } void RdbStoreFuzzTest::TearDownTestCase(void) { - RdbHelper::DeleteRdbStore(RdbStoreFuzzTest::DATABASE_NAME); + if (RdbHelper::DeleteRdbStore(RdbStoreFuzzTest::DATABASE_NAME) != E_OK) { + return; + } } -bool RdbInsertFuzz(const uint8_t *data, size_t size) +bool RdbStoreFuzzTest::InsertData(std::shared_ptr &store, const uint8_t *data, size_t size) { - std::shared_ptr &store = RdbStoreFuzzTest::store_; - bool result = true; + if (data == nullptr) { + return false; + } + int64_t id; ValuesBucket values; + + std::string tableName(data, data + size); std::string valName(data, data + size); int valAge = static_cast(size); double valSalary = static_cast(size); - values.PutString("name", valName + "test1"); + + values.PutString("name", valName); values.PutInt("age", valAge); values.PutDouble("salary", valSalary); - values.PutBlob("blobType", std::vector {*data}); - int errCode = store->Insert(id, "test", values); - if (errCode != E_OK) { - result = false; + values.PutBlob("blobType", std::vector (data, data + size)); + + return store->Insert(id, tableName, values); +} + +bool RdbInsertFuzz(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return false; } - values.Clear(); - values.PutString("name", valName + "test2"); - values.PutInt("age", valAge + 1); - values.PutDouble("salary", valSalary + salaryChange); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - store->Insert(id, "test", values); + + std::shared_ptr &store = RdbStoreFuzzTest::store_; + bool result = true; + + int errCode = RdbStoreFuzzTest::InsertData(store, data, size); if (errCode != E_OK) { result = false; } + store->ExecuteSql("DELETE FROM test"); return result; } bool RdbDeleteFuzz(const uint8_t *data, size_t size) { + if (data == nullptr) { + return false; + } + std::shared_ptr &store = RdbStoreFuzzTest::store_; + bool result = true; - int64_t id; - int deletedRows; + int errCode = RdbStoreFuzzTest::InsertData(store, data, size); + if (errCode != E_OK) { + result = false; + } - ValuesBucket values; - std::string valName(data, data + size); - int valAge = static_cast(size); - double valSalary = static_cast(size); - values.PutString("name", valName + "test1"); - values.PutInt("age", valAge); - values.PutDouble("salary", valSalary); - values.PutBlob("blobType", std::vector {*data}); - store->Insert(id, "test", values); - - values.Clear(); - values.PutString("name", valName + "test2"); - values.PutInt("age", valAge + 1); - values.PutDouble("salary", valSalary + salaryChange); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - store->Insert(id, "test", values); - int errCode = store->Delete(deletedRows, "test", "id = 1"); + int deletedRows; + std::string tableName(data, data + size); + std::string whereClause(data, data + size); + errCode = store->Delete(deletedRows, tableName, whereClause); if (errCode != E_OK) { result = false; } + store->ExecuteSql("DELETE FROM test"); return result; } bool RdbUpdateFuzz(const uint8_t *data, size_t size) { + if (data == nullptr) { + return false; + } + std::shared_ptr &store = RdbStoreFuzzTest::store_; bool result = true; - int64_t id; - int changedRows; + int errCode = RdbStoreFuzzTest::InsertData(store, data, size); + if (errCode != E_OK) { + result = false; + } + + int changedRows; ValuesBucket values; std::string valName(data, data + size); - int valAge = static_cast(size); - double valSalary = static_cast(size); - values.PutString("name", valName + "test1"); + int valAge = static_cast(*data); + double valSalary = static_cast(*data); + std::string whereClause(data, data + size); + std::string tableName(data, data + size); + + values.PutString("name", valName); values.PutInt("age", valAge); values.PutDouble("salary", valSalary); - values.PutBlob("blobType", std::vector {*data}); - store->Insert(id, "test", values); - - values.Clear(); - values.PutString("name", valName + "test2"); - values.PutInt("age", valAge + 1); - values.PutDouble("salary", valSalary + salaryChange); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - int errCode = store->Update(changedRows, "test", values, "name = ?", - std::vector { valName + "test1" }); + values.PutBlob("blobType", std::vector (data, data + size)); + + errCode = store->Update(changedRows, tableName, values, whereClause, + std::vector { valName }); if (errCode != E_OK) { result = false; } @@ -165,131 +177,105 @@ bool RdbUpdateFuzz(const uint8_t *data, size_t size) return result; } -void DBInsert(std::string &valName, int &valAge, double &valSalary, - std::shared_ptr &store, const uint8_t *data) -{ - int64_t id; - ValuesBucket values; - values.PutString("name", valName + "test1"); - values.PutInt("age", valAge); - values.PutDouble("salary", valSalary); - values.PutBlob("blobType", std::vector {*data}); - store->Insert(id, "test", values); - - values.Clear(); - values.PutString("name", valName + "test2"); - values.PutInt("age", valAge + 1); - values.PutDouble("salary", valSalary + salaryChange); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - store->Insert(id, "test", values); - - values.Clear(); - values.PutString("name", valName + "test3"); - values.PutInt("age", valAge + ageChange); - values.PutDouble("salary", valSalary + salaryChanges); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - store->Insert(id, "test", values); - - values.Clear(); - values.PutString("name", valName + "test4"); - values.PutInt("age", valAge + ageChange); - values.PutDouble("salary", valSalary + salaryChanges); - values.PutBlob("blobType", std::vector {*data, *data + 1}); - store->Insert(id, "test", values); -} - void RdbQueryFuzz1(const uint8_t *data, size_t size) { - std::string valName(data, data + size); - int valAge = static_cast(size); - double valSalary = static_cast(size); + if (data == nullptr) { + return; + } + std::shared_ptr &store = RdbStoreFuzzTest::store_; - AbsRdbPredicates predicates("test"); - std::vector columns; - columns.push_back("id"); - columns.push_back("name"); - columns.push_back("age"); - columns.push_back("salary"); - columns.push_back("blobType"); - DBInsert(valName, valAge, valSalary, store, data); - - predicates.EqualTo("name", valName + "test1"); - store->Query(predicates, columns); + + int errCode = RdbStoreFuzzTest::InsertData(store, data, size); + if (errCode != E_OK) { + return; + } + + std::string tableName(data, data + size); + std::string valName(data, data + size); + std::string vectorElem(data, data + size); + AbsRdbPredicates predicates(tableName); + + predicates.EqualTo("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.NotEqualTo("name", valName + "test1"); - store->Query(predicates, columns); + predicates.NotEqualTo("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.Contains("name", valName + "test1"); - store->Query(predicates, columns); + predicates.Contains("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.BeginsWith("name", valName + "test1"); - store->Query(predicates, columns); + predicates.BeginsWith("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.EndsWith("name", valName + "test1"); - store->Query(predicates, columns); + predicates.EndsWith("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.Like("name", valName + "test1"); - store->Query(predicates, columns); + predicates.Like("name", valName); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.Glob("name", valName + "?est1"); - store->Query(predicates, columns); + predicates.Glob("name", valName); + store->Query(predicates, {vectorElem}); store->ExecuteSql("DELETE FROM test"); } void RdbQueryFuzz2(const uint8_t *data, size_t size) { - std::string valName(data, data + size); - int valAge = static_cast(size); - double valSalary = static_cast(size); + if (data == nullptr) { + return; + } + std::shared_ptr &store = RdbStoreFuzzTest::store_; - AbsRdbPredicates predicates("test"); - std::vector columns; - columns.push_back("id"); - columns.push_back("name"); - columns.push_back("age"); - columns.push_back("salary"); - columns.push_back("blobType"); - DBInsert(valName, valAge, valSalary, store, data); + + int errCode = RdbStoreFuzzTest::InsertData(store, data, size); + if (errCode != E_OK) { + return; + } + + std::string tableName(data, data + size); + std::string valName(data, data + size); + std::string valAge(data, data + size); + std::string valAgeChange(data, data + size); + std::string vectorElem(data, data + size); + + AbsRdbPredicates predicates(tableName); predicates.Clear(); - predicates.Between("age", std::to_string(valAge), std::to_string(valAge + ageChange)); - store->Query(predicates, columns); + predicates.Between("age", valAge, valAgeChange); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.NotBetween("age", std::to_string(valAge), std::to_string(valAge + 1)); - store->Query(predicates, columns); + predicates.NotBetween("age", valAge, valAgeChange); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.GreaterThan("age", std::to_string(valAge)); - store->Query(predicates, columns); + predicates.GreaterThan("age", valAge); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.LessThan("age", std::to_string(valAge + ageChange)); - store->Query(predicates, columns); + predicates.LessThan("age", valAgeChange); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.GreaterThanOrEqualTo("age", std::to_string(valAge)); - store->Query(predicates, columns); + predicates.GreaterThanOrEqualTo("age", valAge); + store->Query(predicates, {vectorElem}); predicates.Clear(); - predicates.LessThanOrEqualTo("age", std::to_string(valAge + ageChange)); - store->Query(predicates, columns); + predicates.LessThanOrEqualTo("age", valAgeChange); + store->Query(predicates, {vectorElem}); - std::vector agrsIn = {std::to_string(INT_MAX)}; predicates.Clear(); - predicates.In("name", agrsIn); - store->Query(predicates, columns); + predicates.In("name", {vectorElem}); + store->Query(predicates, {vectorElem}); predicates.Clear(); - std::vector agrsNotin = {std::to_string(INT_MAX), std::to_string(INT_MIN)}; - predicates.NotIn("name", agrsNotin); - store->Query(predicates, columns); + predicates.NotIn("name", {vectorElem}); + store->Query(predicates, {vectorElem}); store->ExecuteSql("DELETE FROM test"); } } @@ -306,5 +292,4 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) OHOS::RdbQueryFuzz2(data, size); OHOS::RdbStoreFuzzTest::TearDownTestCase(); return 0; -} - +} \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp b/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp index 5a44ecb4..77c3a8cc 100644 --- a/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_helper_test.cpp @@ -54,6 +54,7 @@ void RdbHelperTest::SetUpTestCase(void) void RdbHelperTest::TearDownTestCase(void) { + RdbHelper::DeleteRdbStore(rdbStorePath); } void RdbHelperTest::SetUp(void) diff --git a/relational_store/test/native/rdb/unittest/rdb_predicates_join_test.cpp b/relational_store/test/native/rdb/unittest/rdb_predicates_join_test.cpp index 02a80a74..ab0e5bb0 100644 --- a/relational_store/test/native/rdb/unittest/rdb_predicates_join_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_predicates_join_test.cpp @@ -50,12 +50,13 @@ public: const std::string RdbStorePredicateJoinTest::DATABASE_NAME = RDB_TEST_PATH + "predicates_join_test.db"; std::shared_ptr RdbStorePredicateJoinTest::store = nullptr; -const std::string CREATE_TABLE_USER_SQL = std::string("CREATE TABLE IF NOT EXISTS user ") + - std::string("(userId INTEGER PRIMARY KEY AUTOINCREMENT, firstName TEXT, lastName TEXT,") + - std::string("age INTEGER , balance REAL NOT NULL)"); -const std::string CREATE_TABLE_BOOK_SQL = std::string("CREATE TABLE IF NOT EXISTS book ") + - std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, userId INTEGER,") + - std::string("FOREIGN KEY (userId) REFERENCES user (userId) ON UPDATE NO ACTION ON DELETE CASCADE)"); +const std::string CREATE_TABLE_USER_SQL = "CREATE TABLE IF NOT EXISTS user " + "(userId INTEGER PRIMARY KEY AUTOINCREMENT, firstName TEXT, lastName TEXT," + "age INTEGER , balance REAL NOT NULL)"; +const std::string CREATE_TABLE_BOOK_SQL = "CREATE TABLE IF NOT EXISTS book " + "(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, userId INTEGER," + "FOREIGN KEY (userId) REFERENCES user (userId) " + "ON UPDATE NO ACTION ON DELETE CASCADE)"; class PredicateJoinTestOpenCallback : public RdbOpenCallback { public: @@ -371,3 +372,110 @@ HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_004, TestSize.Level1) std::shared_ptr allDataTypes = RdbStorePredicateJoinTest::store->Query(predicates, columns); EXPECT_EQ(5, ResultSize(allDataTypes)); } + +/* * + * @tc.name: RdbStore_LeftOuterJoin_005 + * @tc.desc: Abnormal testCase of RdbPredicates for LeftOuterJoin, if tableName is "" + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_005, TestSize.Level1) +{ + RdbPredicates predicates("user"); + + std::vector clauses; + clauses.push_back("user.userId = book.userId"); + std::vector joinTypes; + + predicates.LeftOuterJoin("")->On(clauses); + EXPECT_EQ(joinTypes, predicates.GetJoinTypes()); + EXPECT_EQ(joinTypes, predicates.GetJoinConditions()); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateJoinTest::store->Query(predicates, columns); + EXPECT_EQ(5, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_LeftOuterJoin_006 + * @tc.desc: Abnormal testCase of RdbPredicates for LeftOuterJoin, if the join condition is [] + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_006, TestSize.Level1) +{ + RdbPredicates predicates("user"); + + std::vector clauses; + std::vector joinTypes; + joinTypes.push_back("LEFT OUTER JOIN"); + + predicates.LeftOuterJoin("book")->On(clauses); + EXPECT_EQ(joinTypes, predicates.GetJoinTypes()); + EXPECT_EQ(clauses, predicates.GetJoinConditions()); +} + +/* * + * @tc.name: RdbStore_LeftOuterJoin_007 + * @tc.desc: Abnormal testCase of RdbPredicates for LeftOuterJoin, if fields is [] + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_007, TestSize.Level1) +{ + RdbPredicates predicates("user"); + + std::vector fields; + predicates.LeftOuterJoin("book")->Using(fields)->EqualTo("name", "SanGuo"); + + std::vector joinTypes; + joinTypes.push_back("LEFT OUTER JOIN"); + EXPECT_EQ(joinTypes, predicates.GetJoinTypes()); + EXPECT_EQ(fields, predicates.GetJoinConditions()); +} + +/* * + * @tc.name: RdbStore_LeftOuterJoin_008 + * @tc.desc: Abnormal testCase of RdbPredicates for LeftOuterJoin, if tableName is "" + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_008, TestSize.Level1) +{ + RdbPredicates predicates("user"); + + std::vector fields; + fields.push_back("userId"); + predicates.LeftOuterJoin("")->Using(fields)->EqualTo("name", "SanGuo"); + + std::vector joinTypes; + EXPECT_EQ(joinTypes, predicates.GetJoinTypes()); + EXPECT_EQ(joinTypes, predicates.GetJoinConditions()); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateJoinTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_LeftOuterJoin_009 + * @tc.desc: Abnormal testCase of RdbPredicates for LeftOuterJoin, if join count rather than 1 + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateJoinTest, RdbStore_LeftOuterJoin_009, TestSize.Level1) +{ + RdbPredicates predicates("user"); + + std::vector fields; + fields.push_back("userId"); + predicates.LeftOuterJoin("book")->LeftOuterJoin("book"); + EXPECT_EQ(2, predicates.GetJoinCount()); + predicates.Using(fields)->EqualTo("name", "SanGuo"); + + std::vector joinTypes{"LEFT OUTER JOIN", "LEFT OUTER JOIN"}; + EXPECT_EQ(joinTypes, predicates.GetJoinTypes()); + EXPECT_EQ(0, predicates.GetJoinCount()); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateJoinTest::store->Query(predicates, columns); + EXPECT_NE(allDataTypes, nullptr); + allDataTypes->Close(); +} \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp index 0cef7ef9..14254fde 100644 --- a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp @@ -29,6 +29,7 @@ #include "rdb_helper.h" #include "rdb_open_callback.h" #include "rdb_predicates.h" +#include "abs_rdb_predicates.h" using namespace testing::ext; using namespace OHOS::NativeRdb; @@ -326,22 +327,25 @@ public: std::shared_ptr RdbStorePredicateTest::store = nullptr; const std::string RdbStorePredicateTest::DATABASE_NAME = RDB_TEST_PATH + "predicates_test.db"; -const std::string CREATE_TABLE_ALL_DATA_TYPE_SQL = std::string("CREATE TABLE IF NOT EXISTS AllDataType ") + - std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, integerValue INTEGER , longValue INTEGER , ") + - std::string("shortValue INTEGER , booleanValue INTEGER , doubleValue REAL , floatValue REAL , ") + - std::string("stringValue TEXT , blobValue BLOB , clobValue TEXT , byteValue INTEGER , ") + - std::string("timeValue INTEGER , characterValue TEXT , primIntValue INTEGER ,") + - std::string("primLongValue INTEGER NOT NULL, primShortValue INTEGER NOT NULL, ") + - std::string("primFloatValue REAL NOT NULL, primDoubleValue REAL NOT NULL, ") + - std::string("primBooleanValue INTEGER NOT NULL, primByteValue INTEGER NOT NULL, ") + - std::string("primCharValue TEXT, `order` INTEGER);"); - -const std::string ALL_DATA_TYPE_INSERT_SQL = std::string("INSERT INTO AllDataType (id, integerValue, longValue, ") + - std::string("shortValue, booleanValue, doubleValue, floatValue, stringValue, blobValue, ") + - std::string("clobValue, byteValue, timeValue, characterValue, primIntValue, primLongValue, ") + - std::string("primShortValue, primFloatValue, primDoubleValue, ") + - std::string("primBooleanValue, primByteValue, primCharValue, `order`) ") + - std::string("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"); +const std::string CREATE_TABLE_ALL_DATA_TYPE_SQL = "CREATE TABLE IF NOT EXISTS AllDataType " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, integerValue INTEGER , longValue INTEGER , " + "shortValue INTEGER , booleanValue INTEGER , doubleValue REAL , floatValue REAL , " + "stringValue TEXT , blobValue BLOB , clobValue TEXT , byteValue INTEGER , " + "timeValue INTEGER , characterValue TEXT , primIntValue INTEGER ," + "primLongValue INTEGER NOT NULL, primShortValue INTEGER NOT NULL, " + "primFloatValue REAL NOT NULL, primDoubleValue REAL NOT NULL, " + "primBooleanValue INTEGER NOT NULL, primByteValue INTEGER NOT NULL, " + "primCharValue TEXT, `orderr` INTEGER);"; + +const std::string CREATE_TABLE_PERSON_SQL = "CREATE TABLE IF NOT EXISTS person " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT , age INTEGER , REAL INTEGER);"; + +const std::string ALL_DATA_TYPE_INSERT_SQL = "INSERT INTO AllDataType (id, integerValue, longValue, " + "shortValue, booleanValue, doubleValue, floatValue, stringValue, blobValue, " + "clobValue, byteValue, timeValue, characterValue, primIntValue, primLongValue, " + "primShortValue, primFloatValue, primDoubleValue, " + "primBooleanValue, primByteValue, primCharValue, `orderr`) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"; class PredicateTestOpenCallback : public RdbOpenCallback { public: @@ -387,6 +391,7 @@ void RdbStorePredicateTest::TearDown(void) {} void RdbStorePredicateTest::GenerateAllDataTypeTable() { RdbStorePredicateTest::store->ExecuteSql(CREATE_TABLE_ALL_DATA_TYPE_SQL); + RdbStorePredicateTest::store->ExecuteSql(CREATE_TABLE_PERSON_SQL); AllDataType *dataType1 = RdbStorePredicateTest::BuildAllDataType1(); @@ -568,6 +573,40 @@ time_t RdbStorePredicateTest::DateMakeTime(std::vector data) return time; } +/* * + * @tc.name: RdbStore_RdbPredicates_001 + * @tc.desc: Abnormal testCase of RdbPredicates, if tableName is "" + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_RdbPredicates_001, TestSize.Level1) +{ + AbsRdbPredicates predicates(""); + predicates.EqualTo("integerValue", "1"); + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_RdbPredicates_002 + * @tc.desc: Abnormal testCase of RdbPredicates, if tableNames is [] or counts is rather than 1 + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_RdbPredicates_002, TestSize.Level1) +{ + std::vector tableEmpty; + std::vector tables({"AllDataType", "person"}); + + AbsRdbPredicates predicates1(tableEmpty); + AbsRdbPredicates predicates2(tables); + predicates2.EqualTo("id", "1"); + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates2, columns); + EXPECT_EQ(1, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + /* * * @tc.name: RdbStore_EqualTo_001 * @tc.desc: Normal testCase of RdbPredicates for EqualTo @@ -665,6 +704,22 @@ int RdbStorePredicateTest::ResultSize(std::shared_ptr &resultSet) return count; } +/* * + * @tc.name: RdbStore_NotEqualTo_001 + * @tc.desc: Abnormal testCase of RdbPredicates for NotEqualTo, if field is "" + * @tc.type: FUNC + * @tc.require: AR000FKD4F + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_NotEqualTo_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.NotEqualTo("", "1"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); +} + /* * * @tc.name: RdbStore_NotEqualTo_002 * @tc.desc: Normal testCase of RdbPredicates for NotEqualTo @@ -692,6 +747,7 @@ void RdbStorePredicateTest::CalendarTest002(RdbPredicates predicates1) std::shared_ptr allDataTypes9 = RdbStorePredicateTest::store->Query(predicates1, columns); EXPECT_EQ(2, ResultSize(allDataTypes9)); } + void RdbStorePredicateTest::BasicDataTypeTest002(RdbPredicates predicates1) { std::vector columns; @@ -1384,7 +1440,7 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_ClearMethod_022, TestSize.Level1) predicates1.Clear(); EXPECT_EQ("AllDataType", predicates1.GetTableName()); - EXPECT_EQ(-1, predicates1.GetLimit()); + EXPECT_EQ(-2147483648, predicates1.GetLimit()); EXPECT_EQ(true, predicates1.GetWhereClause().empty()); EXPECT_EQ(true, predicates1.GetWhereArgs().empty()); @@ -1507,18 +1563,19 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_KeywordMethod_024, TestSize.Level1) ->Or() ->EqualTo("integerValue", std::to_string(INT_MAX)) ->EndWrap()->OrderByDesc("integerValue")->Limit(2); - std::vector columns = {"booleanValue", "doubleValue", "order"}; + std::vector columns = {"booleanValue", "doubleValue", "orderr"}; std::shared_ptr allDataTypes1 = RdbStorePredicateTest::store->Query(predicates1, columns); allDataTypes1->GoToFirstRow(); - EXPECT_EQ(2, ResultSize(allDataTypes1)); + int count = ResultSize(allDataTypes1); + EXPECT_EQ(2, count); EXPECT_EQ("AllDataType", predicates1.GetTableName()); EXPECT_EQ(2, predicates1.GetLimit()); EXPECT_EQ(true, predicates1.GetWhereClause().find("stringValue") != std::string::npos); - std::vector agrs = predicates1.GetWhereArgs(); - auto ret = find(agrs.begin(), agrs.end(), "ABCDEFGHIJKLMN"); - EXPECT_EQ(true, ret != agrs.end()); + std::vector args = predicates1.GetWhereArgs(); + auto ret = find(args.begin(), args.end(), "ABCDEFGHIJKLMN"); + EXPECT_EQ(true, ret != args.end()); std::vector lists = {"ohos", "bazhahei", "zhaxidelie"}; predicates1.SetJoinTableNames(lists); @@ -1528,25 +1585,25 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_KeywordMethod_024, TestSize.Level1) predicates1.SetOrder("ohos"); predicates1.Distinct(); - agrs = predicates1.GetJoinTableNames(); - ret = find(agrs.begin(), agrs.end(), "zhaxidelie"); - EXPECT_EQ(true, ret != agrs.end()); + args = predicates1.GetJoinTableNames(); + ret = find(args.begin(), args.end(), "zhaxidelie"); + EXPECT_EQ(true, ret != args.end()); EXPECT_EQ(1, predicates1.GetJoinCount()); - agrs = predicates1.GetJoinConditions(); - ret = find(agrs.begin(), agrs.end(), "zhaxidelie"); - EXPECT_EQ(true, ret != agrs.end()); + args = predicates1.GetJoinConditions(); + ret = find(args.begin(), args.end(), "zhaxidelie"); + EXPECT_EQ(true, ret != args.end()); - agrs = predicates1.GetJoinTypes(); - ret = find(agrs.begin(), agrs.end(), "zhaxidelie"); - EXPECT_EQ(true, ret != agrs.end()); + args = predicates1.GetJoinTypes(); + ret = find(args.begin(), args.end(), "zhaxidelie"); + EXPECT_EQ(true, ret != args.end()); EXPECT_EQ(true, predicates1.GetJoinClause().find("ohos") != std::string::npos); EXPECT_EQ("ohos", predicates1.GetOrder()); EXPECT_EQ(true, predicates1.IsDistinct()); predicates1.Clear(); EXPECT_EQ("AllDataType", predicates1.GetTableName()); - EXPECT_EQ(-1, predicates1.GetLimit()); + EXPECT_EQ(-2147483648, predicates1.GetLimit()); EXPECT_EQ(true, predicates1.GetWhereClause().empty()); EXPECT_EQ(true, predicates1.GetWhereArgs().empty()); @@ -1577,9 +1634,9 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_ToString_025, TestSize.Level1) ->OrderByDesc("integerValue") ->Limit(2); std::string toString = predicates1.ToString(); - std::string result = "TableName = AllDataType, {WhereClause:`stringValue` = ? AND ( `integerValue` = ? OR " - "`integerValue` = ? ) , whereArgs:{ABCDEFGHIJKLMN, 1, 2147483647, }, order:`integerValue` " - "DESC , group:, index:, limit:2, offset:-1, distinct:0, isNeedAnd:1, isSorted:1}"; + std::string result = "TableName = AllDataType, {WhereClause:stringValue = ? AND ( integerValue = ? OR " + "integerValue = ? ) , whereArgs:{ABCDEFGHIJKLMN, 1, 2147483647, }, order:integerValue " + "DESC , group:, index:, limit:2, offset:-2147483648, distinct:0, isNeedAnd:1, isSorted:1}"; EXPECT_EQ(result, toString); } @@ -1618,4 +1675,493 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_GetDistributedPredicates_027, TestSize. EXPECT_EQ(distributedRdbPredicates.operations_[0].operator_, OHOS::DistributedRdb::EQUAL_TO); EXPECT_EQ(distributedRdbPredicates.operations_[0].field_, "stringValue"); EXPECT_EQ(distributedRdbPredicates.operations_[0].values_[0], "ABCDEFGHIJKLMN"); +} + +/* * + * @tc.name: RdbStore_EndWrap_001 + * @tc.desc: Abnormal testCase of RdbPredicates for EndWrap, fail to add ')' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_EndWrap_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.NotEqualTo("id", "1")->BeginWrap()->EndWrap(); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Or_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Or, fail to add 'OR' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Or_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.EqualTo("id", "1")->BeginWrap()->Or(); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_And_001 + * @tc.desc: Abnormal testCase of RdbPredicates for And, fail to add 'AND' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_And_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.EqualTo("id", "1")->BeginWrap()->And(); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Contain_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Contain, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Contain_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Contains("", "1"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_BeginsWith_001 + * @tc.desc: Abnormal testCase of RdbPredicates for BeginsWith, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_BeginsWith_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.BeginsWith("", "s"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_EndsWith_001 + * @tc.desc: Abnormal testCase of RdbPredicates for EndsWith, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_EndsWith_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.EndsWith("", "s"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_IsNull_001 + * @tc.desc: Abnormal testCase of RdbPredicates for IsNull, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_IsNull_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.IsNull(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_IsNotNull_001 + * @tc.desc: Abnormal testCase of RdbPredicates for IsNotNull, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_IsNotNull_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.IsNotNull(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Like_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Like, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Like_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Like("", "wks"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Glob_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Glob, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Glob_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Glob("", "wks"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Between_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Between, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Between_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Between("", "1", "4"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_NotBetween_001 + * @tc.desc: Abnormal testCase of RdbPredicates for NotBetween, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_NotBetween_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.NotBetween("", "1", "4"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_GreaterThan_001 + * @tc.desc: Abnormal testCase of RdbPredicates for GreaterThan, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GreaterThan_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.GreaterThan("", "1"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_LessThan_001 + * @tc.desc: Abnormal testCase of RdbPredicates for LessThan, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_LessThan_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.LessThan("", "4"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_GreaterThanOrEqualTo_001 + * @tc.desc: Abnormal testCase of RdbPredicates for GreaterThanOrEqualTo, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GreaterThanOrEqualTo_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.LessThan("", "1"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_LessThanOrEqualTo_001 + * @tc.desc: Abnormal testCase of RdbPredicates for LessThanOrEqualTo, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_LessThanOrEqualTo_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.LessThanOrEqualTo("", "1"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_OrderByDesc_001 + * @tc.desc: Abnormal testCase of RdbPredicates for OrderByDesc, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_OrderByDesc_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.OrderByDesc(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_OrderByAsc_001 + * @tc.desc: Abnormal testCase of RdbPredicates for OrderByAsc, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_OrderByAsc_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.OrderByAsc(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Limit_001 + * @tc.desc: Abnormal testCase of RdbPredicates for OrderByAsc, if set limit param twice + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Limit_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Limit(2)->Limit(2); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(2, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Offset_001 + * @tc.desc: Abnormal testCase of RdbPredicates for Offset, if set Offset param twice + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Offset_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.Limit(2)->Offset(1)->Offset(1); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(2, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_Offset_002 + * @tc.desc: Abnormal testCase of RdbPredicates for Offset, if Offset param is less than 1 + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_Offset_002, TestSize.Level1) +{ + RdbPredicates predicates1("AllDataType"); + predicates1.Limit(2)->Offset(0); + + std::vector columns1; + std::shared_ptr allDataTypes1 = RdbStorePredicateTest::store->Query(predicates1, columns1); + EXPECT_EQ(2, ResultSize(allDataTypes1)); + allDataTypes1->Close(); + + RdbPredicates predicates2("AllDataType"); + predicates2.Limit(2)->Offset(-1); + + std::vector columns2; + std::shared_ptr allDataTypes2 = RdbStorePredicateTest::store->Query(predicates2, columns2); + EXPECT_EQ(2, ResultSize(allDataTypes2)); + allDataTypes2->Close(); +} + +/* * + * @tc.name: RdbStore_GroupBy_001 + * @tc.desc: Abnormal testCase of RdbPredicates for GroupBy, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GroupBy_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.GroupBy({}); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_GroupBy_002 + * @tc.desc: Abnormal testCase of RdbPredicates for GroupBy, if param is invalid + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GroupBy_002, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.GroupBy({"idx"}); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(0, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_IndexedBy_001 + * @tc.desc: Abnormal testCase of RdbPredicates for IndexedBy, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_IndexedBy_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.IndexedBy(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_IndexedBy_002 + * @tc.desc: Normal testCase of RdbPredicates for IndexedBy + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_IndexedBy_002, TestSize.Level1) +{ + RdbStorePredicateTest::store->ExecuteSql("CREATE INDEX orderr_index ON AllDataType(orderr)"); + + RdbPredicates predicates("AllDataType"); + predicates.IndexedBy("orderr_index"); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_In_001 + * @tc.desc: Abnormal testCase of RdbPredicates for In, if field is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_In_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.In("", {"1", "3"}); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_In_002 + * @tc.desc: Abnormal testCase of RdbPredicates for In, if values is [] + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_In_002, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.In("id", {}); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_SetOrder_001 + * @tc.desc: Abnormal testCase of RdbPredicates for SetOrder, if order is '' + * @tc.type: FUNC + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_SetOrder_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.SetOrder(""); + + std::vector columns; + std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(3, ResultSize(allDataTypes)); + allDataTypes->Close(); +} + +/* * + * @tc.name: RdbStore_GetStatement_GetBindArgs_001 + * @tc.desc: Normal testCase of RdbPredicates for GetStatement and GetBindArgs method + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GetStatement_GetBnidArgs_001, TestSize.Level1) +{ + RdbPredicates predicates("AllDataType"); + predicates.EqualTo("stringValue", "ABCDEFGHIJKLMN") + ->BeginWrap() + ->EqualTo("integerValue", "1") + ->Or() + ->EqualTo("integerValue", std::to_string(INT_MAX)) + ->EndWrap() + ->OrderByDesc("integerValue") + ->Limit(-1, -1); + + std::vector columns; + int count = 0; + std::shared_ptr resultSet = RdbStorePredicateTest::store->Query(predicates, columns); + resultSet->GetRowCount(count); + EXPECT_EQ(2, count); + + std::string statement = predicates.GetStatement(); + std::vector bindArgs = predicates.GetBindArgs(); + EXPECT_EQ(statement, " WHERE stringValue = ? AND ( integerValue = ? OR integerValue = ? ) ORDER BY " + "integerValue DESC LIMIT -1 OFFSET -1"); + EXPECT_EQ(bindArgs[0], "ABCDEFGHIJKLMN"); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp index 89472c04..58bc4bbe 100644 --- a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp @@ -1166,4 +1166,228 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_020, TestSize.Le std::string data1ValueByIndex = rowEntity.Get(0); EXPECT_EQ("hello", data1ValueByIndex); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_021 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for PrepareStep, if len(qrySql) is less than 3 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_021, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SE", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + std::vector columnNames; + int ret = resultSet->GetAllColumnNames(columnNames); + EXPECT_EQ(E_EXECUTE_IN_STEP_QUERY, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_022 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for PrepareStep, if qrySql is invalid + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_022, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT FROM", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + std::vector columnNames; + int ret = resultSet->GetAllColumnNames(columnNames); + EXPECT_EQ(-1, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_023 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetAllColumnNames, if resultSet is closed + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_023, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->Close(); + + std::vector columnNames; + int ret = resultSet->GetAllColumnNames(columnNames); + EXPECT_EQ(E_STEP_RESULT_CLOSED, ret); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_024 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetRowCount, if resultSet is closed + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_024, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->Close(); + + int count = 0; + int ret = resultSet->GetRowCount(count); + EXPECT_EQ(E_STEP_RESULT_CLOSED, ret); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_025 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GoToRow, if position is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_025, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + int ret = resultSet->GoToRow(-10); + EXPECT_EQ(E_ERROR, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_026 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetBlob, if position is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_026, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->GoToFirstRow(); + + std::vector blob; + int ret = resultSet->GetBlob(-10, blob); + EXPECT_EQ(E_INVALID_COLUMN_INDEX, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_027 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetAsset, if col is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_027, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->GoToFirstRow(); + + ValueObject::Asset value; + int ret = resultSet->GetAsset(-10, value); + EXPECT_EQ(E_INVALID_COLUMN_INDEX, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_028 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetAssets, if col is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_028, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->GoToFirstRow(); + + ValueObject::Assets value; + int ret = resultSet->GetAssets(-10, value); + EXPECT_EQ(E_INVALID_COLUMN_INDEX, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_029 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for GetSize, if columnIndex is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_029, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->GoToFirstRow(); + + size_t size; + int ret = resultSet->GetSize(-10, size); + EXPECT_EQ(E_INVALID_COLUMN_INDEX, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_030 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for IsColumnNull, if columnIndex is less than 0 + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_030, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + resultSet->GoToFirstRow(); + + bool isNUll; + int ret = resultSet->IsColumnNull(-10, isNUll); + EXPECT_EQ(E_INVALID_COLUMN_INDEX, ret); + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_031 + * @tc.desc: Abnormal testcase of SqliteSharedResultSet for Close, if close resultSet twice + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_031, TestSize.Level1) +{ + GenerateDefaultTable(); + std::vector selectionArgs; + std::shared_ptr resultSet = + RdbSqliteSharedResultSetTest::store->QuerySql("SELECT * FROM test", selectionArgs); + EXPECT_NE(resultSet, nullptr); + + int ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); + + bool isClosed = resultSet->IsClosed(); + EXPECT_EQ(isClosed, true); + + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp index 50c5d86d..a6182930 100644 --- a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp @@ -320,12 +320,12 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_003, TestSize.Level1) iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(3, position); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); bResultSet = true; iRet = resultSet->IsAtFirstRow(bResultSet); @@ -369,17 +369,17 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_004, TestSize.Level1) iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(0, position); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsAtFirstRow(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); } /* * @@ -455,32 +455,32 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_006, TestSize.Level1) EXPECT_NE(E_OK, resultSet->GoToFirstRow()); int position = INT_MIN; - bool bResultSet = true; + bool bResultSet = false; int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(0, position); iRet = resultSet->IsAtFirstRow(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); EXPECT_NE(E_OK, resultSet->GoToNextRow()); EXPECT_NE(E_OK, resultSet->GoToFirstRow()); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsAtFirstRow(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); } /* * @@ -513,7 +513,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_007, TestSize.Level1) } iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(3, position); bResultSet = false; iRet = resultSet->IsEnded(bResultSet); @@ -540,7 +540,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_008, TestSize.Level1) bool bResultSet = false; int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(0, position); iRet = resultSet->IsEnded(bResultSet); EXPECT_EQ(E_OK, iRet); @@ -551,7 +551,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_008, TestSize.Level1) } iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(1, position); bResultSet = false; iRet = resultSet->IsEnded(bResultSet); @@ -1368,7 +1368,7 @@ HWTEST_F(RdbStepResultSetTest, testGoToPrevious007, TestSize.Level1) iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(3, position); bResultSet = false; iRet = resultSet->IsEnded(bResultSet); @@ -1574,12 +1574,12 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep010, TestSize.Level1) iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(-1, position); + EXPECT_EQ(3, position); - bResultSet = true; + bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); bResultSet = true; iRet = resultSet->IsAtFirstRow(bResultSet); @@ -1627,3 +1627,150 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep011, TestSize.Level1) EXPECT_EQ(E_OK, iRet); EXPECT_EQ(arrLen, stringValueLen); } + +/* * + * @tc.name: testSqlStep012 + * @tc.desc: Normal testcase of SqlStep for constructor std::vector + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep012, TestSize.Level1) +{ + GenerateDefaultEmptyTable(); + + std::string insertSql = "INSERT INTO test (data1, data2, data3, data4) VALUES (?, ?, ?, ?);"; + const char arr[] = { 0X11, 0X22, 0X33, 0X44, 0X55, 0X00, 0X66, 0X77, 0X00 }; + size_t arrLen = sizeof(arr); + uint8_t uValue = 66; + std::vector typeBlob; + typeBlob.push_back(uValue); + store->ExecuteSql( + insertSql, std::vector { ValueObject(std::string(arr, arrLen)), ValueObject((int)10), + ValueObject((double)1.0), ValueObject((std::vector)typeBlob) }); + + std::shared_ptr resultSet = store->QueryByStep("SELECT ? FROM test", + std::vector {ValueObject((std::string)"data1")}); + EXPECT_NE(resultSet, nullptr); + + int iRet = resultSet->GoToFirstRow(); + EXPECT_EQ(E_OK, iRet); + bool bResultSet = false; + iRet = resultSet->IsAtFirstRow(bResultSet); + EXPECT_EQ(E_OK, iRet); + EXPECT_EQ(bResultSet, true); + + EXPECT_EQ(E_OK, resultSet->Close()); +} + +/* * + * @tc.name: testSqlStep013 + * @tc.desc: Abnormal testcase of SqlStep, if close resultSet before query + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep013, TestSize.Level1) +{ + GenerateDefaultTable(); + + std::shared_ptr resultSet = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + + EXPECT_EQ(E_OK, resultSet->Close()); + + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GoToNextRow()); + + std::vector columnNames; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetAllColumnNames(columnNames)); + + ColumnType columnType; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetColumnType(1, columnType)); + + std::vector blob; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetBlob(1, blob)); + + std::string valueString; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetString(1, valueString)); + + int valueInt; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetInt(1, valueInt)); + + int64_t valueInt64; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetLong(1, valueInt64)); + + double valuedouble; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetDouble(1, valuedouble)); + + std::string modifyTime; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->GetModifyTime(modifyTime)); + + ValueObject object; + EXPECT_EQ(E_STEP_RESULT_CLOSED, resultSet->Get(4, object)); +} + +/* * + * @tc.name: testSqlStep014 + * @tc.desc: Abnormal testcase of SqlStep for GoToRow, if connection counts over limit + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep014, TestSize.Level1) +{ + GenerateDefaultTable(); + + std::shared_ptr resultSet1 = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet1, nullptr); + + std::shared_ptr resultSet2 = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet2, nullptr); + + std::shared_ptr resultSet3 = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet2, nullptr); + + std::shared_ptr resultSet4 = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet2, nullptr); + + std::shared_ptr resultSet5 = store->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet2, nullptr); + + EXPECT_EQ(E_CON_OVER_LIMIT, resultSet5->GoToRow(1)); + + EXPECT_EQ(E_OK, resultSet1->Close()); + EXPECT_EQ(E_OK, resultSet2->Close()); + EXPECT_EQ(E_OK, resultSet3->Close()); + EXPECT_EQ(E_OK, resultSet4->Close()); + EXPECT_EQ(E_OK, resultSet5->Close()); +} + +/* * + * @tc.name: testSqlStep015 + * @tc.desc: Abnormal testcase of SqlStep for QueryByStep, if sql is inValid + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep015, TestSize.Level1) +{ + GenerateDefaultTable(); + + std::shared_ptr resultSet = store->QueryByStep("SE"); + EXPECT_NE(resultSet, nullptr); + + std::vector columnNames; + EXPECT_EQ(E_EXECUTE_IN_STEP_QUERY, resultSet->GetAllColumnNames(columnNames)); + + EXPECT_EQ(E_OK, resultSet->Close()); +} + +/* * + * @tc.name: testSqlStep016 + * @tc.desc: Abnormal testcase of SqlStep for GetSize, if rowPos is inValid + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep016, TestSize.Level1) +{ + GenerateDefaultTable(); + + std::shared_ptr resultSet = store->QueryByStep("SE"); + EXPECT_NE(resultSet, nullptr); + + size_t size; + EXPECT_EQ(E_STEP_RESULT_QUERY_NOT_EXECUTED, resultSet->GetSize(2, size)); + + EXPECT_EQ(E_OK, resultSet->Close()); + EXPECT_EQ(true, resultSet->IsClosed()); +} \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp index f07f8502..577a3e79 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp @@ -894,4 +894,19 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_027, TestSize.Level1) EXPECT_EQ(E_OK, resultSet8->Close()); EXPECT_EQ(E_OK, resultSet9->Close()); EXPECT_EQ(E_OK, resultSet10->Close()); +} + +/** + * @tc.name: RdbStoreConfig_028 + * @tc.desc: test RdbStoreConfig interfaces: SetDataGroupId/GetDataGroupId + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_028, TestSize.Level1) +{ + const std::string dbPath = RDB_TEST_PATH + "config_test.db"; + RdbStoreConfig config(dbPath); + + std::string dataGroupId = "123456"; + config.SetDataGroupId(dataGroupId); + EXPECT_EQ(dataGroupId, config.GetDataGroupId()); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp index fae7564b..473ed8eb 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp @@ -29,6 +29,7 @@ class SubObserver : public RdbStoreObserver { public: virtual ~SubObserver() {} void OnChange(const std::vector& devices) override; + void OnChange() override; }; class RdbStoreSubTest : public testing::Test { @@ -58,6 +59,7 @@ void RdbStoreSubTest::SetUpTestCase(void) void RdbStoreSubTest::TearDownTestCase(void) { + RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME); } void RdbStoreSubTest::SetUp() @@ -88,6 +90,25 @@ void SubObserver::OnChange(const std::vector &devices) { } +void SubObserver::OnChange() +{ + const std::string CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER, salary " + "REAL, blobType BLOB)"; + RdbStoreSubTest::store->ExecuteSql(CREATE_TABLE_TEST); + ValuesBucket values; + int64_t id; + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); + values.PutDouble("salary", 100.5); + values.PutBlob("blobType", std::vector{ 1, 2, 3 }); + int ret = RdbStoreSubTest::store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); +} + std::shared_ptr RdbStoreSubTest::CreateRDB(int version) { RdbStoreConfig config(RdbStoreSubTest::MAIN_DATABASE_NAME); @@ -147,3 +168,26 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeCloudDetail, TestSize.Level1) auto status = store->Subscribe({ SubscribeMode::CLOUD_DETAIL }, observer_.get()); EXPECT_EQ(status, E_OK); } + +/** + * @tc.name: RdbStoreSubscribeLocal + * @tc.desc: RdbStoreSubscribe + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeLocal, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(observer_, nullptr) << "observer is null"; + auto status = store->Subscribe({ SubscribeMode::LOCAL, "observer" }, observer_.get()); + EXPECT_EQ(status, E_OK); + + status = store->Notify("observer"); + EXPECT_EQ(status, E_OK); + + std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); + int count; + resultSet->GetRowCount(count); + EXPECT_EQ(1, count); +} diff --git a/relational_store/test/native/rdb_bms_adapter/BUILD.gn b/relational_store/test/native/rdb_bms_adapter/BUILD.gn index 641dc28f..9ecdb677 100644 --- a/relational_store/test/native/rdb_bms_adapter/BUILD.gn +++ b/relational_store/test/native/rdb_bms_adapter/BUILD.gn @@ -33,12 +33,14 @@ ohos_unittest("RdbBMSAdapterTest") { "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", - "relational_store:native_rdb", "relational_store:rdb_bms_adapter", "resource_management:global_resmgr", ] - deps = [ "//third_party/googletest:gtest_main" ] + deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", + "//third_party/googletest:gtest_main", + ] } ############################################################################### diff --git a/relational_store/test/native/rdb_data_ability_adapter/BUILD.gn b/relational_store/test/native/rdb_data_ability_adapter/BUILD.gn index 9b0ceb9d..988dc48a 100644 --- a/relational_store/test/native/rdb_data_ability_adapter/BUILD.gn +++ b/relational_store/test/native/rdb_data_ability_adapter/BUILD.gn @@ -39,11 +39,13 @@ ohos_unittest("NativeDataAbilityAdapterTest") { "c_utils:utils", "hilog:libhilog", "relational_store:native_dataability", - "relational_store:native_rdb", "relational_store:rdb_data_ability_adapter", ] - deps = [ "//third_party/googletest:gtest_main" ] + deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", + "//third_party/googletest:gtest_main", + ] } ############################################################################### diff --git a/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp b/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp index 3f01727d..ce957501 100644 --- a/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp +++ b/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp @@ -107,7 +107,7 @@ HWTEST_F(DataAbilityUtilsTest, DataAbilityUtilsTest_002, TestSize.Level1) predicates->SetOrder(order); predicates->Distinct(); - std::string whereClause = "`name` = ? "; + std::string whereClause = "name = ? "; auto dataSharePredicates = RdbDataAbilityUtils::ToDataSharePredicates(*predicates); std::string dataShareWhereClause = dataSharePredicates.GetWhereClause(); EXPECT_EQ(dataShareWhereClause, whereClause); diff --git a/relational_store/test/native/rdb_data_share_adapter/BUILD.gn b/relational_store/test/native/rdb_data_share_adapter/BUILD.gn index 68cacefd..99516322 100644 --- a/relational_store/test/native/rdb_data_share_adapter/BUILD.gn +++ b/relational_store/test/native/rdb_data_share_adapter/BUILD.gn @@ -52,11 +52,11 @@ ohos_unittest("RdbDataShareAdapterTest") { external_deps = [ "c_utils:utils", "hilog:libhilog", - "relational_store:native_rdb", "relational_store:rdb_data_share_adapter", ] deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", "//third_party/googletest:gtest_main", "//third_party/icu/icu4c:shared_icui18n", "//third_party/icu/icu4c:shared_icuuc", diff --git a/relational_store/test/ndk/BUILD.gn b/relational_store/test/ndk/BUILD.gn index 47d3a71e..aa491d59 100644 --- a/relational_store/test/ndk/BUILD.gn +++ b/relational_store/test/ndk/BUILD.gn @@ -35,8 +35,8 @@ ohos_unittest("NativeRdbNdkTest") { sources = [ "${relational_store_base_path}/interfaces/ndk/src/relational_cursor.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_predicates.cpp", + "${relational_store_base_path}/interfaces/ndk/src/relational_predicates_objects.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_store.cpp", - "${relational_store_base_path}/interfaces/ndk/src/relational_value_object.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_values_bucket.cpp", "unittest/rdb_cursor_test.cpp", "unittest/rdb_predicates_test.cpp", diff --git a/relational_store/test/ndk/unittest/common.h b/relational_store/test/ndk/unittest/common.h index 111c940b..3c775958 100644 --- a/relational_store/test/ndk/unittest/common.h +++ b/relational_store/test/ndk/unittest/common.h @@ -21,7 +21,7 @@ namespace OHOS { namespace NativeRdb { -static const std::string RDB_TEST_PATH = "/data/test/"; +static constexpr const char *RDB_TEST_PATH = "/data/test/"; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp index 2e375584..65ab58c9 100644 --- a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include "common.h" #include "relational_store.h" @@ -28,23 +30,29 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); + static void InitRdbConfig() + { + config_.dataBaseDir = RDB_TEST_PATH; + config_.storeName = "rdb_cursor_test.db"; + config_.bundleName = ""; + config_.moduleName = ""; + config_.securityLevel = OH_Rdb_SecurityLevel::S1; + config_.isEncrypt = false; + config_.selfSize = sizeof(OH_Rdb_Config); + } + static OH_Rdb_Config config_; }; -std::string cursorTestPath_ = RDB_TEST_PATH + "rdb_cursor_test.db"; OH_Rdb_Store *cursorTestRdbStore_; - +OH_Rdb_Config RdbNdkCursorTest::config_ = {0}; void RdbNdkCursorTest::SetUpTestCase(void) { - OH_Rdb_Config config = {0}; - config.path = cursorTestPath_.c_str(); - config.securityLevel = OH_Rdb_SecurityLevel::S1; - config.isEncrypt = false; - + InitRdbConfig(); + mkdir(config_.dataBaseDir, 0770); int errCode = 0; char table[] = "test"; - cursorTestRdbStore_ = OH_Rdb_GetOrOpen(&config, &errCode); + cursorTestRdbStore_ = OH_Rdb_GetOrOpen(&config_, &errCode); EXPECT_NE(cursorTestRdbStore_, NULL); - char createTableSql[] = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, " "data3 FLOAT, data4 BLOB, data5 TEXT);"; errCode = OH_Rdb_Execute(cursorTestRdbStore_, createTableSql); @@ -79,14 +87,14 @@ void RdbNdkCursorTest::SetUpTestCase(void) errCode = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket); EXPECT_EQ(errCode, 3); - valueBucket->destroyValuesBucket(valueBucket); + valueBucket->destroy(valueBucket); } void RdbNdkCursorTest::TearDownTestCase(void) { delete cursorTestRdbStore_; cursorTestRdbStore_ = NULL; - OH_Rdb_DeleteStore(cursorTestPath_.c_str()); + OH_Rdb_DeleteStore(&config_); } void RdbNdkCursorTest::SetUp(void) @@ -130,8 +138,8 @@ HWTEST_F(RdbNdkCursorTest, RDB_NDK_cursor_test_001, TestSize.Level1) errCode = cursor->getColumnType(cursor, 5, &type); EXPECT_EQ(type, OH_ColumnType::TYPE_TEXT); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -163,8 +171,8 @@ HWTEST_F(RdbNdkCursorTest, RDB_NDK_cursor_test_002, TestSize.Level1) errCode = cursor->getColumnIndex(cursor, "data5", &columnIndex); EXPECT_EQ(columnIndex, 5); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -196,8 +204,8 @@ HWTEST_F(RdbNdkCursorTest, RDB_NDK_cursor_test_003, TestSize.Level1) errCode = cursor->getColumnName(cursor, 5, name, 6); EXPECT_EQ(strcmp(name, "data5"), 0); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -261,6 +269,6 @@ HWTEST_F(RdbNdkCursorTest, RDB_NDK_cursor_test_004, TestSize.Level1) cursor->isNull(cursor, 3, &isNull); EXPECT_EQ(isNull, true); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } \ No newline at end of file diff --git a/relational_store/test/ndk/unittest/rdb_predicates_test.cpp b/relational_store/test/ndk/unittest/rdb_predicates_test.cpp index 07237480..3bb5a643 100644 --- a/relational_store/test/ndk/unittest/rdb_predicates_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_predicates_test.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include "common.h" #include "relational_store.h" #include "oh_value_object.h" @@ -29,21 +31,28 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); + static void InitRdbConfig() + { + config_.dataBaseDir = RDB_TEST_PATH; + config_.storeName = "rdb_predicates_test.db"; + config_.bundleName = ""; + config_.moduleName = ""; + config_.securityLevel = OH_Rdb_SecurityLevel::S1; + config_.isEncrypt = false; + config_.selfSize = sizeof(OH_Rdb_Config); + } + static OH_Rdb_Config config_; }; -std::string predicatesTestPath_ = RDB_TEST_PATH + "rdb_predicates_test.db"; OH_Rdb_Store *predicatesTestRdbStore_; - +OH_Rdb_Config RdbNdkPredicatesTest::config_ = {0}; void RdbNdkPredicatesTest::SetUpTestCase(void) { - OH_Rdb_Config config; - config.path = predicatesTestPath_.c_str(); - config.securityLevel = OH_Rdb_SecurityLevel::S1; - config.isEncrypt = false; - + InitRdbConfig(); + mkdir(config_.dataBaseDir, 0770); int errCode = 0; char table[] = "test"; - predicatesTestRdbStore_ = OH_Rdb_GetOrOpen(&config, &errCode); + predicatesTestRdbStore_ = OH_Rdb_GetOrOpen(&config_, &errCode); EXPECT_NE(predicatesTestRdbStore_, NULL); char createTableSql[] = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, " @@ -80,14 +89,14 @@ void RdbNdkPredicatesTest::SetUpTestCase(void) errCode = OH_Rdb_Insert(predicatesTestRdbStore_, table, valueBucket); EXPECT_EQ(errCode, 3); - valueBucket->destroyValuesBucket(valueBucket); + valueBucket->destroy(valueBucket); } void RdbNdkPredicatesTest::TearDownTestCase(void) { delete predicatesTestRdbStore_; predicatesTestRdbStore_ = NULL; - OH_Rdb_DeleteStore(predicatesTestPath_.c_str()); + OH_Rdb_DeleteStore(&config_); } void RdbNdkPredicatesTest::SetUp(void) @@ -122,9 +131,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_001, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - predicates->destroyPredicates(predicates); - valueObject->destroyValueObject(valueObject); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -148,9 +157,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_002, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -230,9 +239,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_003, TestSize.Level1) cursor->getText(cursor, 5, data5Value_2, size + 1); EXPECT_EQ(strcmp(data5Value_2, "ABCDEFGHI"), 0); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -255,9 +264,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_004, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 3); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -280,9 +289,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_005, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 0); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -305,9 +314,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_006, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -327,8 +336,8 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_007, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -348,8 +357,8 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_008, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -377,9 +386,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_009, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -403,9 +412,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_010, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -436,8 +445,8 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_011, TestSize.Level1) cursor->getInt64(cursor, columnIndex, &longValue); EXPECT_EQ(longValue, 13800); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -461,9 +470,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_012, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -487,9 +496,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_013, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -515,9 +524,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_014, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 3); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -539,8 +548,8 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_015, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 3); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -567,9 +576,9 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_016, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - errCode = cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + errCode = cursor->destroy(cursor); } /** @@ -591,7 +600,7 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_017, TestSize.Level1) int rowCount = 0; errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - errCode = cursor->close(cursor); + errCode = cursor->destroy(cursor); predicates->clear(predicates); predicates->notEqualTo(predicates, "data1", valueObject); @@ -600,11 +609,10 @@ HWTEST_F(RdbNdkPredicatesTest, RDB_NDK_predicates_test_017, TestSize.Level1) errCode = cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - errCode = cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + cursor->destroy(cursor); } - /** * @tc.name: RDB_NDK_predicates_test_018 * @tc.desc: Normal testCase of NDK Predicates for table name is NULL. diff --git a/relational_store/test/ndk/unittest/rdb_store_test.cpp b/relational_store/test/ndk/unittest/rdb_store_test.cpp index a9a8ef47..645640d3 100644 --- a/relational_store/test/ndk/unittest/rdb_store_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_store_test.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include "common.h" #include "relational_store.h" #include "relational_store_error_code.h" @@ -29,27 +31,35 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); + static void InitRdbConfig() + { + config_.dataBaseDir = RDB_TEST_PATH; + config_.storeName = "rdb_predicates_test.db"; + config_.bundleName = ""; + config_.moduleName = ""; + config_.securityLevel = OH_Rdb_SecurityLevel::S1; + config_.isEncrypt = false; + config_.selfSize = sizeof(OH_Rdb_Config); + } + static OH_Rdb_Config config_; }; -std::string storeTestPath_ = RDB_TEST_PATH + "rdb_store_test.db"; OH_Rdb_Store *storeTestRdbStore_; - +OH_Rdb_Config RdbNdkStoreTest::config_ = {0}; void RdbNdkStoreTest::SetUpTestCase(void) { - OH_Rdb_Config config; - config.path = storeTestPath_.c_str(); - config.securityLevel = OH_Rdb_SecurityLevel::S1; - config.isEncrypt = false; - + InitRdbConfig(); + mkdir(config_.dataBaseDir, 0770); int errCode = 0; - storeTestRdbStore_ = OH_Rdb_GetOrOpen(&config, &errCode); + storeTestRdbStore_ = OH_Rdb_GetOrOpen(&config_, &errCode); EXPECT_NE(storeTestRdbStore_, NULL); } void RdbNdkStoreTest::TearDownTestCase(void) { int errCode = OH_Rdb_CloseStore(storeTestRdbStore_); - errCode = OH_Rdb_DeleteStore(storeTestPath_.c_str()); + EXPECT_EQ(errCode, 0); + errCode = OH_Rdb_DeleteStore(&config_); EXPECT_EQ(errCode, 0); } @@ -137,10 +147,10 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_001, TestSize.Level1) cursor->isNull(cursor, 5, &isNull); EXPECT_EQ(isNull, true); - valueObject->destroyValueObject(valueObject); - valueBucket->destroyValuesBucket(valueBucket); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + valueBucket->destroy(valueBucket); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -213,10 +223,10 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_002, TestSize.Level1) cursor->getText(cursor, 5, data5Value, size + 1); EXPECT_EQ(strcmp(data5Value, "ABCDEFGH"), 0); - valueObject->destroyValueObject(valueObject); - valueBucket->destroyValuesBucket(valueBucket); - predicates->destroyPredicates(predicates); - cursor->close(cursor); + valueObject->destroy(valueObject); + valueBucket->destroy(valueBucket); + predicates->destroy(predicates); + cursor->destroy(cursor); } /** @@ -259,8 +269,8 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_003, TestSize.Level1) cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - valueBucket->destroyValuesBucket(valueBucket); - cursor->close(cursor); + valueBucket->destroy(valueBucket); + cursor->destroy(cursor); } /** @@ -303,8 +313,8 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_004, TestSize.Level1) cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 0); - valueBucket->destroyValuesBucket(valueBucket); - cursor->close(cursor); + valueBucket->destroy(valueBucket); + cursor->destroy(cursor); } /** @@ -332,21 +342,21 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_005, TestSize.Level1) int rowCount = 0; cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - cursor->close(cursor); + cursor->destroy(cursor); - std::string backupPath1 = RDB_TEST_PATH + "a.db"; + std::string backupPath1 = RDB_TEST_PATH + std::string("a.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath1.c_str()); EXPECT_EQ(errCode, 0); errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); EXPECT_EQ(errCode, 2); - std::string backupPath2 = RDB_TEST_PATH + "b.db"; + std::string backupPath2 = RDB_TEST_PATH + std::string("b.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath2.c_str()); EXPECT_EQ(errCode, 0); errCode = OH_Rdb_Insert(storeTestRdbStore_, "test", valueBucket); EXPECT_EQ(errCode, 3); - std::string backupPath3 = RDB_TEST_PATH + "c.db"; + std::string backupPath3 = RDB_TEST_PATH + std::string("c.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath3.c_str()); EXPECT_EQ(errCode, 0); @@ -361,21 +371,21 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_005, TestSize.Level1) cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - cursor->close(cursor); + cursor->destroy(cursor); errCode = OH_Rdb_Restore(storeTestRdbStore_, backupPath2.c_str()); EXPECT_EQ(errCode, 0); cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - cursor->close(cursor); + cursor->destroy(cursor); errCode = OH_Rdb_Restore(storeTestRdbStore_, backupPath3.c_str()); EXPECT_EQ(errCode, 0); cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 4); - cursor->close(cursor); + cursor->destroy(cursor); // Continuous restore errCode = OH_Rdb_Restore(storeTestRdbStore_, backupPath3.c_str()); @@ -384,8 +394,8 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_005, TestSize.Level1) cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 4); - valueBucket->destroyValuesBucket(valueBucket); - cursor->close(cursor); + valueBucket->destroy(valueBucket); + cursor->destroy(cursor); } /** @@ -413,7 +423,7 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_006, TestSize.Level1) int rowCount = 0; cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - cursor->close(cursor); + cursor->destroy(cursor); std::string backupPath = "backup.db"; errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath.c_str()); @@ -423,7 +433,7 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_006, TestSize.Level1) cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - cursor->close(cursor); + cursor->destroy(cursor); std::string restorePath = "error.db"; errCode = OH_Rdb_Restore(storeTestRdbStore_, restorePath.c_str()); @@ -439,13 +449,13 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_006, TestSize.Level1) cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 2); - cursor->close(cursor); + cursor->destroy(cursor); backupPath = ""; errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath.c_str()); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_FILE_PATH); - backupPath = RDB_TEST_PATH + "/backup/backup.db"; + backupPath = RDB_TEST_PATH + std::string("/backup/backup.db"); errCode = OH_Rdb_Backup(storeTestRdbStore_, backupPath.c_str()); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_FILE_PATH); @@ -457,7 +467,7 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_006, TestSize.Level1) errCode = OH_Rdb_Restore(storeTestRdbStore_, restorePath.c_str()); EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_FILE_PATH); - valueBucket->destroyValuesBucket(valueBucket); + valueBucket->destroy(valueBucket); } /** @@ -526,8 +536,8 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_008, TestSize.Level1) cursor->getRowCount(cursor, &rowCount); EXPECT_EQ(rowCount, 1); - valueBucket->destroyValuesBucket(valueBucket); - cursor->close(cursor); + valueBucket->destroy(valueBucket); + cursor->destroy(cursor); } /** @@ -606,11 +616,11 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_009, TestSize.Level1) cursor->getText(cursor, 5, data5Value, size + 1); EXPECT_EQ(strcmp(data5Value, "ABCDEFG"), 0); - valueObject->destroyValueObject(valueObject); - predicates->destroyPredicates(predicates); - predicates2->destroyPredicates(predicates2); - valueBucket->destroyValuesBucket(valueBucket); - cursor->close(cursor); + valueObject->destroy(valueObject); + predicates->destroy(predicates); + predicates2->destroy(predicates2); + valueBucket->destroy(valueBucket); + cursor->destroy(cursor); } /** @@ -637,5 +647,5 @@ HWTEST_F(RdbNdkStoreTest, RDB_NDK_store_test_010, TestSize.Level1) OH_Cursor *cursor = OH_Rdb_ExecuteQuery(storeTestRdbStore_, querySql); EXPECT_EQ(cursor, NULL); - valueBucket->destroyValuesBucket(valueBucket); + valueBucket->destroy(valueBucket); } \ No newline at end of file diff --git a/udmf/CMakeLists.txt b/udmf/CMakeLists.txt index 416e22bb..8435f24f 100644 --- a/udmf/CMakeLists.txt +++ b/udmf/CMakeLists.txt @@ -27,10 +27,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/innerkits/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/innerkits/data) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jskits/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jskits/data) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkitsimpl/distributeddatafwk/include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkitsimpl/distributeddatafwk/src) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkits/distributeddata/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/frameworks/common) +#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkitsimpl/distributeddatafwk/include) +#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkitsimpl/distributeddatafwk/src) +#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kv_store/innerkits/distributeddata/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/base/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../utils_native/safwk/native/include) diff --git a/udmf/framework/common/tlv_object.h b/udmf/framework/common/tlv_object.h index cca092be..19af67fe 100644 --- a/udmf/framework/common/tlv_object.h +++ b/udmf/framework/common/tlv_object.h @@ -193,7 +193,7 @@ public: if (!ReadHead(head)) { return false; } - if (head.len == 0) { + if (head.len == 0 || head.len != sizeof(T)) { return false; } if (!HasExpectBuffer(head.len)) { @@ -466,6 +466,9 @@ private: inline bool HasExpectBuffer(const uint32_t expectLen) const { + if (buffer_== nullptr) { + return false; + } return buffer_->size() >= cursor_ && buffer_->size() - cursor_ >= expectLen; } diff --git a/udmf/framework/common/tlv_util.cpp b/udmf/framework/common/tlv_util.cpp index 235d1417..f7023291 100644 --- a/udmf/framework/common/tlv_util.cpp +++ b/udmf/framework/common/tlv_util.cpp @@ -20,6 +20,9 @@ namespace TLVUtil { template<> bool CountBufferSize(const std::shared_ptr &input, TLVObject &data) { + if (input == nullptr) { + return false; + } data.Count(input->GetType()); data.Count(input->GetUid()); auto type = input->GetType(); @@ -229,13 +232,14 @@ bool CountBufferSize(const Runtime &input, TLVObject &data) data.Count(input.dataVersion); data.Count(input.createPackage); data.Count(input.deviceId); + data.Count(input.recordTotalNum); return true; } template<> bool CountBufferSize(const UnifiedData &input, TLVObject &data) { - int32_t size = input.GetRecords().size(); + int32_t size = static_cast(input.GetRecords().size()); data.Count(size); for (auto record : input.GetRecords()) { if (!CountBufferSize(record, data)) { @@ -248,7 +252,7 @@ bool CountBufferSize(const UnifiedData &input, TLVObject &data) template<> bool CountBufferSize(const std::vector &input, TLVObject &data) { - int32_t size = input.size(); + int32_t size = static_cast(input.size()); data.Count(size); for (auto unifiedData : input) { if (!CountBufferSize(unifiedData, data)) { @@ -1183,7 +1187,7 @@ bool Writing(const UnifiedData &input, TLVObject &data) data.UpdateSize(); } - int32_t size = input.GetRecords().size(); + int32_t size = static_cast(input.GetRecords().size()); if (!Writing(size, data)) { return false; } @@ -1221,7 +1225,7 @@ bool Writing(const std::vector &input, TLVObject &data) } data.UpdateSize(); - int32_t size = input.size(); + int32_t size = static_cast(input.size()); if (!Writing(size, data)) { return false; } @@ -1393,6 +1397,9 @@ bool Writing(const Runtime &input, TLVObject &data) if (!Writing(input.deviceId, data)) { return false; } + if (!Writing(input.recordTotalNum, data)) { + return false; + } return true; } @@ -1410,6 +1417,7 @@ bool Reading(Runtime &output, TLVObject &data) int64_t lastModifiedTime; std::string createPackage; std::string deviceId; + uint32_t recordTotalNum; if (!Reading(key, data)) { return false; } @@ -1447,6 +1455,9 @@ bool Reading(Runtime &output, TLVObject &data) if (!Reading(deviceId, data)) { return false; } + if (!Reading(recordTotalNum, data)) { + return false; + } output.key = key; output.isPrivate = isPrivate; output.privileges = privileges; @@ -1457,6 +1468,7 @@ bool Reading(Runtime &output, TLVObject &data) output.lastModifiedTime = lastModifiedTime; output.createPackage = createPackage; output.deviceId = deviceId; + output.recordTotalNum = recordTotalNum; return true; } } // namespace TLVUtil diff --git a/udmf/framework/innerkitsimpl/data/unified_data.cpp b/udmf/framework/innerkitsimpl/data/unified_data.cpp index 7062a7e0..497a492a 100644 --- a/udmf/framework/innerkitsimpl/data/unified_data.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_data.cpp @@ -76,6 +76,15 @@ std::vector UnifiedData::GetUDTypes() return typeSet; } +std::string UnifiedData::GetTypes() +{ + std::string types; + for (const std::shared_ptr &record : records_) { + types.append("-").append(UD_TYPE_MAP.at(record->GetType())); + } + return types; +} + bool UnifiedData::IsEmpty() const { return records_.empty(); diff --git a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp index ceb0b5ca..e1d94e15 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp @@ -21,7 +21,7 @@ #include "accesstoken_kit.h" #include "nativetoken_kit.h" -#include "framework/common/logger.h" +#include "logger.h" #include "udmf_client.h" #include "application_defined_record.h" #include "audio.h" @@ -207,8 +207,7 @@ void UdmfClientTest::GetEmptyData(QueryOption &option) { UnifiedData data; auto status = UdmfClient::GetInstance().GetData(option, data); - EXPECT_EQ(status, E_OK); - EXPECT_TRUE(data.IsEmpty()); + EXPECT_EQ(status, E_NOT_FOUND); } /** diff --git a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp index 8ec95699..4698c3ea 100644 --- a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp +++ b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp @@ -392,7 +392,7 @@ bool NapiDataUtils::IsNull(napi_env env, napi_value value) } if (type == napi_string) { size_t len; - status = napi_get_value_string_utf8(env, value, NULL, 0, &len); + napi_get_value_string_utf8(env, value, NULL, 0, &len); return len == 0; } return false; diff --git a/udmf/framework/jskitsimpl/unittest/UdmfCallbackJsTest.js b/udmf/framework/jskitsimpl/unittest/UdmfCallbackJsTest.js index 50ac19dc..b8d9f764 100644 --- a/udmf/framework/jskitsimpl/unittest/UdmfCallbackJsTest.js +++ b/udmf/framework/jskitsimpl/unittest/UdmfCallbackJsTest.js @@ -259,7 +259,7 @@ describe('UdmfCallbackJSTest', function () { console.info(TAG, `insert success. The key: ${data}`); UDMF.queryData(optionsValid, function (err, data) { expect(err).assertUndefined(); - console.info(TAG, `query success.`); + console.info(TAG, 'query success.'); expect(data.length).assertEqual(2); done(); }); diff --git a/udmf/framework/service/udmf_service_client.cpp b/udmf/framework/service/udmf_service_client.cpp index ecaab7ec..1d2a8875 100644 --- a/udmf/framework/service/udmf_service_client.cpp +++ b/udmf/framework/service/udmf_service_client.cpp @@ -71,9 +71,34 @@ sptr UdmfServiceClient::GetDistributedKvData LOG_ERROR(UDMF_SERVICE, "initialize proxy failed."); return nullptr; } + auto deathRecipientPtr = new (std::nothrow)ServiceDeathRecipient(); + if (deathRecipientPtr == nullptr) { + return nullptr; + } + if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(deathRecipientPtr))) { + LOG_ERROR(UDMF_SERVICE, "Add death recipient fail!"); + } return kvDataServiceProxy_; } +UdmfServiceClient::ServiceDeathRecipient::ServiceDeathRecipient() +{ + LOG_INFO(UDMF_SERVICE, "Construct!"); +} + +UdmfServiceClient::ServiceDeathRecipient::~ServiceDeathRecipient() +{ + LOG_INFO(UDMF_SERVICE, "Destruct!"); +} + +void UdmfServiceClient::ServiceDeathRecipient::OnRemoteDied(const wptr &remote) +{ + LOG_WARN(UDMF_SERVICE, "DistributedDataService die!"); + std::lock_guard lockGuard(mutex_); + kvDataServiceProxy_ = nullptr; + instance_ = nullptr; +} + int32_t UdmfServiceClient::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { LOG_INFO(UDMF_SERVICE, "start"); diff --git a/udmf/framework/service/udmf_service_client.h b/udmf/framework/service/udmf_service_client.h index c61740bb..1877196e 100644 --- a/udmf/framework/service/udmf_service_client.h +++ b/udmf/framework/service/udmf_service_client.h @@ -20,8 +20,7 @@ #include #include "ikvstore_data_service.h" -#include "iremote_broker.h" - +#include "iremote_object.h" #include "udmf_service.h" #include "udmf_service_proxy.h" @@ -43,6 +42,14 @@ public: int32_t Sync(const QueryOption &query, const std::vector &devices) override; private: + class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { + public: + ServiceDeathRecipient(); + virtual ~ServiceDeathRecipient(); + + void OnRemoteDied(const wptr &remote) override; + }; + static std::shared_ptr instance_; static std::mutex mutex_; static sptr kvDataServiceProxy_; diff --git a/udmf/interfaces/innerkits/common/error_code.h b/udmf/interfaces/innerkits/common/error_code.h index f50a2518..d27d9354 100644 --- a/udmf/interfaces/innerkits/common/error_code.h +++ b/udmf/interfaces/innerkits/common/error_code.h @@ -17,6 +17,7 @@ #define UDMF_ERROR_CODE_H #include +#include #include @@ -39,8 +40,24 @@ enum Status : int32_t { E_INVALID_PARAMETERS, E_DB_ERROR, E_UNKNOWN, + E_FS_ERROR, + E_NOT_FOUND, E_BUTT, }; + +static const std::unordered_map ERROR_MAP { + { Status::E_OK, "E_OK" }, + { Status::E_WRITE_PARCEL_ERROR, "E_WRITE_PARCEL_ERROR" }, + { Status::E_READ_PARCEL_ERROR, "E_READ_PARCEL_ERROR" }, + { Status::E_IPC, "E_IPC" }, + { Status::E_ERROR, "E_ERROR" }, + { Status::E_NO_PERMISSION, "E_NO_PERMISSION" }, + { Status::E_INVALID_PARAMETERS, "E_INVALID_PARAMETERS" }, + { Status::E_DB_ERROR, "E_DB_ERROR" }, + { Status::E_UNKNOWN, "E_UNKNOWN" }, + { Status::E_FS_ERROR, "E_FS_ERROR" }, + { Status::E_NOT_FOUND, "E_NOT_FOUND" } +}; } // namespace UDMF } // namespace OHOS #endif // UDMF_ERROR_CODE_H \ No newline at end of file diff --git a/udmf/interfaces/innerkits/common/unified_types.h b/udmf/interfaces/innerkits/common/unified_types.h index 10d6faf7..63a63020 100644 --- a/udmf/interfaces/innerkits/common/unified_types.h +++ b/udmf/interfaces/innerkits/common/unified_types.h @@ -60,6 +60,7 @@ struct Runtime { std::string createPackage; // device ID of the data source std::string deviceId; + std::uint32_t recordTotalNum {}; }; /* diff --git a/udmf/interfaces/innerkits/data/unified_data.h b/udmf/interfaces/innerkits/data/unified_data.h index 2cc052d5..0b55e85e 100644 --- a/udmf/interfaces/innerkits/data/unified_data.h +++ b/udmf/interfaces/innerkits/data/unified_data.h @@ -35,6 +35,7 @@ public: std::vector> GetRecords() const; std::vector GetUDTypes(); + std::string GetTypes(); bool IsEmpty() const; -- Gitee