From 176cab121cd953784fc4cace76b942819afa04b9 Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Wed, 9 Mar 2022 14:25:13 +0800 Subject: [PATCH 1/2] add distributed screen code Signed-off-by: hwzhangchuang --- LICENSE | 178 ++++++++ OAT.xml | 65 +++ README.en.md | 36 -- README.md | 39 -- README_ZH.md | 87 ++++ bundle.json | 87 ++++ common/BUILD.gn | 47 ++ common/include/dscreen_constants.h | 126 ++++++ common/include/dscreen_errcode.h | 94 ++++ common/include/dscreen_log.h | 43 ++ common/include/dscreen_util.h | 28 ++ common/src/dscreen_log.cpp | 87 ++++ common/src/dscreen_util.cpp | 97 +++++ distributedscreen.gni | 25 ++ figures/distributedscreen_arch.png | Bin 0 -> 24264 bytes .../innerkits/native_cpp/screen_sink/BUILD.gn | 55 +++ .../include/dscreen_sink_handler.h | 59 +++ .../screen_sink/include/dscreen_sink_proxy.h | 45 ++ .../screen_sink/include/idscreen_sink.h | 44 ++ .../screen_sink/src/dscreen_sink_handler.cpp | 136 ++++++ .../screen_sink/src/dscreen_sink_proxy.cpp | 123 ++++++ .../native_cpp/screen_source/BUILD.gn | 58 +++ .../callback/dscreen_source_callback.h | 48 +++ .../callback/dscreen_source_callback_stub.h | 45 ++ .../callback/idscreen_source_callback.h | 39 ++ .../include/dscreen_source_handler.h | 64 +++ .../include/dscreen_source_proxy.h | 49 +++ .../screen_source/include/idscreen_source.h | 51 +++ .../src/callback/dscreen_source_callback.cpp | 79 ++++ .../callback/dscreen_source_callback_stub.cpp | 69 +++ .../src/dscreen_source_handler.cpp | 166 ++++++++ .../src/dscreen_source_proxy.cpp | 145 +++++++ sa_profile/4807.xml | 27 ++ sa_profile/4808.xml | 27 ++ sa_profile/BUILD.gn | 23 + screenhandler/BUILD.gn | 56 +++ screenhandler/include/dscreen_handler.h | 56 +++ screenhandler/src/dscreen_handler.cpp | 152 +++++++ .../common/databuffer/include/data_buffer.h | 37 ++ .../common/databuffer/src/data_buffer.cpp | 52 +++ .../screen_channel/include/iscreen_channel.h | 38 ++ .../include/iscreen_channel_listener.h | 34 ++ services/common/test/unittest/BUILD.gn | 20 + .../common/test/unittest/databuffer/BUILD.gn | 68 +++ .../unittest/databuffer/data_buffer_test.cpp | 59 +++ .../unittest/databuffer/data_buffer_test.h | 33 ++ services/common/test/unittest/utils/BUILD.gn | 70 +++ .../utils/dscreen_maprelation_test.cpp | 97 +++++ .../unittest/utils/dscreen_maprelation_test.h | 35 ++ .../test/unittest/utils/video_param_test.cpp | 135 ++++++ .../test/unittest/utils/video_param_test.h | 35 ++ .../utils/include/dscreen_maprelation.h | 65 +++ services/common/utils/include/video_param.h | 59 +++ .../common/utils/src/dscreen_maprelation.cpp | 123 ++++++ services/common/utils/src/video_param.cpp | 116 +++++ services/screenclient/BUILD.gn | 59 +++ services/screenclient/include/screen_client.h | 53 +++ .../include/screen_client_common.h | 31 ++ .../include/screen_client_window_adapter.h | 59 +++ services/screenclient/src/screen_client.cpp | 162 +++++++ .../src/screen_client_window_adapter.cpp | 215 ++++++++++ services/screenclient/test/unittest/BUILD.gn | 69 +++ .../unittest/include/screen_client_test.h | 33 ++ .../screen_client_window_adapter_test.h | 37 ++ .../test/unittest/src/screen_client_test.cpp | 171 ++++++++ .../src/screen_client_window_adapter_test.cpp | 143 +++++++ services/screenservice/sinkservice/BUILD.gn | 83 ++++ .../include/dscreen_sink_service.h | 52 +++ .../include/dscreen_sink_stub.h | 51 +++ .../src/dscreen_sink_service.cpp | 101 +++++ .../dscreenservice/src/dscreen_sink_stub.cpp | 111 +++++ .../screenregionmgr/include/screenregion.h | 66 +++ .../screenregionmgr/include/screenregionmgr.h | 50 +++ .../screenregionmgr/src/screenregion.cpp | 175 ++++++++ .../screenregionmgr/src/screenregionmgr.cpp | 199 +++++++++ services/screenservice/sourceservice/BUILD.gn | 83 ++++ .../dscreenmgr/include/dscreen.h | 123 ++++++ .../dscreenmgr/include/dscreen_manager.h | 77 ++++ .../include/screen_manager_adapter.h | 50 +++ .../sourceservice/dscreenmgr/src/dscreen.cpp | 349 +++++++++++++++ .../dscreenmgr/src/dscreen_manager.cpp | 400 ++++++++++++++++++ .../dscreenmgr/src/screen_manager_adapter.cpp | 130 ++++++ .../callback/dscreen_source_callback_proxy.h | 43 ++ .../include/dscreen_source_service.h | 57 +++ .../include/dscreen_source_stub.h | 52 +++ .../dscreen_source_callback_proxy.cpp | 74 ++++ .../src/dscreen_source_service.cpp | 142 +++++++ .../src/dscreen_source_stub.cpp | 146 +++++++ .../include/screen_data_channel_impl.h | 56 +++ .../src/screen_data_channel_impl.cpp | 197 +++++++++ .../decoder/include/image_decoder_callback.h | 46 ++ .../decoder/include/image_sink_decoder.h | 86 ++++ .../decoder/src/image_decoder_callback.cpp | 68 +++ .../decoder/src/image_sink_decoder.cpp | 346 +++++++++++++++ .../include/iimage_sink_processor.h | 43 ++ .../include/iimage_sink_processor_listener.h | 29 ++ .../include/image_sink_processor.h | 47 ++ .../src/image_sink_processor.cpp | 131 ++++++ .../screentransport/screensinktrans/BUILD.gn | 70 +++ .../include/iscreen_sink_trans.h | 40 ++ .../include/iscreen_sink_trans_callback.h | 31 ++ .../include/screen_sink_trans.h | 67 +++ .../screensinktrans/src/screen_sink_trans.cpp | 309 ++++++++++++++ .../encoder/include/image_encoder_callback.h | 46 ++ .../encoder/include/image_source_encoder.h | 72 ++++ .../encoder/src/image_encoder_callback.cpp | 68 +++ .../encoder/src/image_source_encoder.cpp | 250 +++++++++++ .../include/iimage_source_processor.h | 42 ++ .../iimage_source_processor_listener.h | 32 ++ .../include/image_source_processor.h | 46 ++ .../src/image_source_processor.cpp | 101 +++++ .../screensourcetrans/BUILD.gn | 69 +++ .../include/iscreen_source_trans.h | 40 ++ .../include/iscreen_source_trans_callback.h | 31 ++ .../include/screen_source_trans.h | 85 ++++ .../src/screen_source_trans.cpp | 382 +++++++++++++++++ .../screentransport/test/unittest/BUILD.gn | 23 + .../test/unittest/screendatachannel/BUILD.gn | 82 ++++ .../include/screen_data_channel_impl_test.h | 39 ++ .../src/screen_data_channel_impl_test.cpp | 203 +++++++++ .../unittest/screensinkprocessor/BUILD.gn | 86 ++++ .../include/image_sink_decoder_test.h | 42 ++ .../include/image_sink_processor_test.h | 42 ++ .../src/image_sink_decoder_test.cpp | 344 +++++++++++++++ .../src/image_sink_processor_test.cpp | 193 +++++++++ .../test/unittest/screensinktrans/BUILD.gn | 84 ++++ .../include/screen_sink_trans_test.h | 43 ++ .../src/screen_sink_trans_test.cpp | 258 +++++++++++ .../unittest/screensourceprocessor/BUILD.gn | 75 ++++ .../include/image_source_encoder_test.h | 38 ++ .../include/image_source_processor_test.h | 36 ++ .../src/image_source_encoder_test.cpp | 204 +++++++++ .../src/image_source_processor_test.cpp | 164 +++++++ .../test/unittest/screensourcetrans/BUILD.gn | 75 ++++ .../include/screen_source_trans_test.h | 39 ++ .../src/screen_source_trans_test.cpp | 226 ++++++++++ .../include/screentrans_test_utils.h | 81 ++++ .../include/isoftbus_listener.h | 36 ++ .../softbusadapter/include/softbus_adapter.h | 84 ++++ .../softbusadapter/src/softbus_adapter.cpp | 343 +++++++++++++++ .../softbusadapter/test/unittest/BUILD.gn | 70 +++ .../unittest/include/softbus_adapter_test.h | 40 ++ .../unittest/src/softbus_adapter_test.cpp | 303 +++++++++++++ 143 files changed, 13385 insertions(+), 75 deletions(-) create mode 100644 LICENSE create mode 100644 OAT.xml delete mode 100644 README.en.md delete mode 100644 README.md create mode 100644 README_ZH.md create mode 100644 bundle.json create mode 100644 common/BUILD.gn create mode 100644 common/include/dscreen_constants.h create mode 100644 common/include/dscreen_errcode.h create mode 100644 common/include/dscreen_log.h create mode 100644 common/include/dscreen_util.h create mode 100644 common/src/dscreen_log.cpp create mode 100644 common/src/dscreen_util.cpp create mode 100644 distributedscreen.gni create mode 100644 figures/distributedscreen_arch.png create mode 100644 interfaces/innerkits/native_cpp/screen_sink/BUILD.gn create mode 100644 interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_handler.h create mode 100644 interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_proxy.h create mode 100644 interfaces/innerkits/native_cpp/screen_sink/include/idscreen_sink.h create mode 100644 interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_handler.cpp create mode 100644 interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp create mode 100644 interfaces/innerkits/native_cpp/screen_source/BUILD.gn create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback_stub.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/callback/idscreen_source_callback.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_handler.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_proxy.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/include/idscreen_source.h create mode 100644 interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback.cpp create mode 100644 interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback_stub.cpp create mode 100644 interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_handler.cpp create mode 100644 interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp create mode 100644 sa_profile/4807.xml create mode 100644 sa_profile/4808.xml create mode 100644 sa_profile/BUILD.gn create mode 100644 screenhandler/BUILD.gn create mode 100644 screenhandler/include/dscreen_handler.h create mode 100644 screenhandler/src/dscreen_handler.cpp create mode 100644 services/common/databuffer/include/data_buffer.h create mode 100644 services/common/databuffer/src/data_buffer.cpp create mode 100644 services/common/screen_channel/include/iscreen_channel.h create mode 100644 services/common/screen_channel/include/iscreen_channel_listener.h create mode 100644 services/common/test/unittest/BUILD.gn create mode 100644 services/common/test/unittest/databuffer/BUILD.gn create mode 100644 services/common/test/unittest/databuffer/data_buffer_test.cpp create mode 100644 services/common/test/unittest/databuffer/data_buffer_test.h create mode 100644 services/common/test/unittest/utils/BUILD.gn create mode 100644 services/common/test/unittest/utils/dscreen_maprelation_test.cpp create mode 100644 services/common/test/unittest/utils/dscreen_maprelation_test.h create mode 100644 services/common/test/unittest/utils/video_param_test.cpp create mode 100644 services/common/test/unittest/utils/video_param_test.h create mode 100644 services/common/utils/include/dscreen_maprelation.h create mode 100644 services/common/utils/include/video_param.h create mode 100644 services/common/utils/src/dscreen_maprelation.cpp create mode 100644 services/common/utils/src/video_param.cpp create mode 100644 services/screenclient/BUILD.gn create mode 100644 services/screenclient/include/screen_client.h create mode 100644 services/screenclient/include/screen_client_common.h create mode 100644 services/screenclient/include/screen_client_window_adapter.h create mode 100644 services/screenclient/src/screen_client.cpp create mode 100644 services/screenclient/src/screen_client_window_adapter.cpp create mode 100644 services/screenclient/test/unittest/BUILD.gn create mode 100644 services/screenclient/test/unittest/include/screen_client_test.h create mode 100644 services/screenclient/test/unittest/include/screen_client_window_adapter_test.h create mode 100644 services/screenclient/test/unittest/src/screen_client_test.cpp create mode 100644 services/screenclient/test/unittest/src/screen_client_window_adapter_test.cpp create mode 100644 services/screenservice/sinkservice/BUILD.gn create mode 100644 services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_service.h create mode 100644 services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_stub.h create mode 100644 services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_service.cpp create mode 100644 services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_stub.cpp create mode 100644 services/screenservice/sinkservice/screenregionmgr/include/screenregion.h create mode 100644 services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h create mode 100644 services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp create mode 100644 services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp create mode 100644 services/screenservice/sourceservice/BUILD.gn create mode 100644 services/screenservice/sourceservice/dscreenmgr/include/dscreen.h create mode 100644 services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h create mode 100644 services/screenservice/sourceservice/dscreenmgr/include/screen_manager_adapter.h create mode 100644 services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp create mode 100644 services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp create mode 100644 services/screenservice/sourceservice/dscreenmgr/src/screen_manager_adapter.cpp create mode 100644 services/screenservice/sourceservice/dscreenservice/include/callback/dscreen_source_callback_proxy.h create mode 100644 services/screenservice/sourceservice/dscreenservice/include/dscreen_source_service.h create mode 100644 services/screenservice/sourceservice/dscreenservice/include/dscreen_source_stub.h create mode 100644 services/screenservice/sourceservice/dscreenservice/src/callback/dscreen_source_callback_proxy.cpp create mode 100644 services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp create mode 100644 services/screenservice/sourceservice/dscreenservice/src/dscreen_source_stub.cpp create mode 100644 services/screentransport/screendatachannel/include/screen_data_channel_impl.h create mode 100644 services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp create mode 100644 services/screentransport/screensinkprocessor/decoder/include/image_decoder_callback.h create mode 100644 services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h create mode 100644 services/screentransport/screensinkprocessor/decoder/src/image_decoder_callback.cpp create mode 100644 services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp create mode 100644 services/screentransport/screensinkprocessor/include/iimage_sink_processor.h create mode 100644 services/screentransport/screensinkprocessor/include/iimage_sink_processor_listener.h create mode 100644 services/screentransport/screensinkprocessor/include/image_sink_processor.h create mode 100644 services/screentransport/screensinkprocessor/src/image_sink_processor.cpp create mode 100644 services/screentransport/screensinktrans/BUILD.gn create mode 100644 services/screentransport/screensinktrans/include/iscreen_sink_trans.h create mode 100644 services/screentransport/screensinktrans/include/iscreen_sink_trans_callback.h create mode 100644 services/screentransport/screensinktrans/include/screen_sink_trans.h create mode 100644 services/screentransport/screensinktrans/src/screen_sink_trans.cpp create mode 100644 services/screentransport/screensourceprocessor/encoder/include/image_encoder_callback.h create mode 100644 services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h create mode 100644 services/screentransport/screensourceprocessor/encoder/src/image_encoder_callback.cpp create mode 100644 services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp create mode 100644 services/screentransport/screensourceprocessor/include/iimage_source_processor.h create mode 100644 services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h create mode 100644 services/screentransport/screensourceprocessor/include/image_source_processor.h create mode 100644 services/screentransport/screensourceprocessor/src/image_source_processor.cpp create mode 100644 services/screentransport/screensourcetrans/BUILD.gn create mode 100644 services/screentransport/screensourcetrans/include/iscreen_source_trans.h create mode 100644 services/screentransport/screensourcetrans/include/iscreen_source_trans_callback.h create mode 100644 services/screentransport/screensourcetrans/include/screen_source_trans.h create mode 100644 services/screentransport/screensourcetrans/src/screen_source_trans.cpp create mode 100644 services/screentransport/test/unittest/BUILD.gn create mode 100644 services/screentransport/test/unittest/screendatachannel/BUILD.gn create mode 100644 services/screentransport/test/unittest/screendatachannel/include/screen_data_channel_impl_test.h create mode 100644 services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp create mode 100644 services/screentransport/test/unittest/screensinkprocessor/BUILD.gn create mode 100644 services/screentransport/test/unittest/screensinkprocessor/include/image_sink_decoder_test.h create mode 100644 services/screentransport/test/unittest/screensinkprocessor/include/image_sink_processor_test.h create mode 100644 services/screentransport/test/unittest/screensinkprocessor/src/image_sink_decoder_test.cpp create mode 100644 services/screentransport/test/unittest/screensinkprocessor/src/image_sink_processor_test.cpp create mode 100644 services/screentransport/test/unittest/screensinktrans/BUILD.gn create mode 100644 services/screentransport/test/unittest/screensinktrans/include/screen_sink_trans_test.h create mode 100644 services/screentransport/test/unittest/screensinktrans/src/screen_sink_trans_test.cpp create mode 100644 services/screentransport/test/unittest/screensourceprocessor/BUILD.gn create mode 100644 services/screentransport/test/unittest/screensourceprocessor/include/image_source_encoder_test.h create mode 100644 services/screentransport/test/unittest/screensourceprocessor/include/image_source_processor_test.h create mode 100644 services/screentransport/test/unittest/screensourceprocessor/src/image_source_encoder_test.cpp create mode 100644 services/screentransport/test/unittest/screensourceprocessor/src/image_source_processor_test.cpp create mode 100644 services/screentransport/test/unittest/screensourcetrans/BUILD.gn create mode 100644 services/screentransport/test/unittest/screensourcetrans/include/screen_source_trans_test.h create mode 100644 services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp create mode 100644 services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h create mode 100644 services/softbusadapter/include/isoftbus_listener.h create mode 100644 services/softbusadapter/include/softbus_adapter.h create mode 100644 services/softbusadapter/src/softbus_adapter.cpp create mode 100644 services/softbusadapter/test/unittest/BUILD.gn create mode 100644 services/softbusadapter/test/unittest/include/softbus_adapter_test.h create mode 100644 services/softbusadapter/test/unittest/src/softbus_adapter_test.cpp diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..e454a525 --- /dev/null +++ b/LICENSE @@ -0,0 +1,178 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 00000000..a7d94aed --- /dev/null +++ b/OAT.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index c889106c..00000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# distributed_screen - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 86aba951..00000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# distributed_screen - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 00000000..b2223c47 --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,87 @@ +# **分布式屏幕组件** + +## **简介** + +分布式屏幕是一种屏幕虚拟化能力,支持用户指定任意设备的屏幕作为Display的显示区域。在分布式硬件子系统中,分布式屏幕提供跨设备屏幕能力调用,为OpenHarmony操作系统提供系统投屏、屏幕镜像、屏幕分割等能力的实现。 + +系统架构如下图所示: + +![](figures/distributedscreen_arch.png) + +**屏幕区域管理(ScreenRegionManager)**:管理主控端映射在被控端屏幕上的显示区域的状态,包括为显示区域指定显示的display,设置显示区域的宽高,解码类型等参数。 + +**分布式屏幕管理(DScreenManager)**:管理被控端屏幕的参数和状态,负责主控端相关对象的创建和销毁。 + +**屏幕服务(ScreenService)**:分布式屏幕主控端SA服务和分布式屏幕被控端SA服务,负责处理分布式硬件管理框架的IPC调用 + +**软总线适配器(SoftbusAdapter)**:对接软总线传输接口,为屏幕图像、输入事件等提供封装的统一调用接口,实现设备间的流数据、字节数据传输和交互。 + +**屏幕传输组件(ScreenTransport)**:分布式屏幕传输模块,实现屏幕图像数据编码、解码、发送、接收。 + +**屏幕代理客户端(ScreenClient)**:屏幕图像显示代理客户端,用于在设备上显示其他设备投射过来的屏幕图像数据。 + + +## **目录** + +``` +/foundation/distributedhardware/distributedscreen +├── common # 分布式屏幕公共数据定义,包括常量、错误码、日志、工具等 +├── interface # 分布式屏幕SDK,包含主控端和被控端服务调用接口 +├── sa_profile # 分布式屏幕的SA配置信息 +├── services # 分布式屏幕主控端和被控端功能主体业务实现 +│ └── common # 分布式屏幕功能主控端、被控端共用功能实现 +│ ├── databuffer # 屏幕数据存储定义 +│ └── screen_channel # 屏幕数据传输通道接口定义 +│ └── screenclient # 分布式屏幕代理客户端实现 +│ └── screenservice # 分布式屏幕主体功能实现 +│ └── sinkservice # 分布式屏幕被控端服务功能实现 +│ ├── dscreenservice # 分布式屏幕被控端SA +│ └── screenregionmgr # 分布式屏幕被控端显示区域管理 +│ └── sourceservice # 分布式屏幕主控端服务功能实现 +│ ├── dscreenmgr # 分布式屏幕主控端屏幕管理 +│ └── dscreenservice # 分布式屏幕主控端SA +│ └── screentransport # 分布式屏幕传输组件 +│ ├── screendatachannel # 屏幕数据传输通道,用于传输组件和编解码器之间数据传输 +│ ├── screensinkprocessor # 分布式屏幕被控端数据处理模块,包括解码等 +│ ├── screensinktrans # 分布式屏幕被控端数据传输组件,包含数据传输通道channel和数据处理模块processor +│ ├── screensourceprocessor # 分布式屏幕主控端数据处理模块,包括编码等 +│ └── screensourcetrans # 分布式屏幕主控端数据传输组件,包含数据传输通道channel和数据处理模块processor +│ └── softbusadapter # 软总线接口适配器,为屏幕传输、触控事件传输提供统一传输接口 +└── screenhandler # 分布式屏幕硬件信息上报、设备状态变化通知,由分布式硬件管理框架加载 +``` + +## **约束** +**语言限制**:C++语言。 +**组网环境**:必须确保设备在同一个局域网中。 +**操作系统限制**:OpenHarmony操作系统。 + +## **说明** +### **概念说明** +主控端(source):控制端,通过调用分布式屏幕能力,使用被控端的屏幕用于显示主控端设备的屏幕内容。 +被控端(sink):被控制端,通过分布式屏幕接收主控端的控制,在本地对接窗口用于接收和显示主控端设备的屏幕内容。 + +### **接口说明** +分布式屏幕实现分布式硬件管理框架提供的接口,由分布式硬件管理框架统一调用接口实现虚拟屏幕硬件的创建和注册功能。 + +### **流程说明** +#### **1. 设备开机启动** +系统拉起分布式屏幕的SA服务,Source侧被初始化,相关模块被初始化。 + +#### **2. 设备组网上线** +设备上线后,分布式硬件管理框架同步到上线设备的屏幕硬件信息并使能,使能成功后在系统中会新增虚拟屏幕并通知到窗口子系统,窗口子系统统一管理本地屏幕和分布式屏幕;北向应用通过窗口子系统提供的接口可以查询到分布式屏幕,并按照窗口子系统提供的接口来使用分布式屏幕。 + +#### **3. 屏幕数据流转** +(1)主控端图形子系统将需要发送屏幕数据保存在编码器创建的输入Surface中。 +(2)主控端编码器将输入数据进行编码,并将编码结果返回传输组件screensourcetrans。 +(3)主控端传输组件screensourcetrans将编码后的数据通过传输通道screendatachannel发送到softbusadapter,并经由软总线子系统发送到被控端端设备。 +(4)被控端设备软总线子系统收到屏幕数据后,通过softbusadapter返回给被控端传输通道screendatachannel。 +(5)被控端传输通道screendatachannel将获取到的屏幕数据传递给解码器进行解码。 +(6)解码器将屏幕数据解码,并将解码后的数据保存到被控端代理显示窗口设置到解码器的Surface中,最终由窗口将画面显示在屏幕上。 + +#### **4. 设备下线** +设备下线后,分布式硬件管理框架去使能下线设备的屏幕硬件,本地移除对应的虚拟屏幕并通知窗口子系统,此时下线设备的分布式屏幕不可用。 + +## **涉及仓** +**** +**分布式屏幕** +[distributed_screen](https://gitee.com/openharmony/distributed_screen) \ No newline at end of file diff --git a/bundle.json b/bundle.json new file mode 100644 index 00000000..c89001c4 --- /dev/null +++ b/bundle.json @@ -0,0 +1,87 @@ +{ + "name":"@ohos/distributed_screen", + "description":"distributed hardware screen", + "version":"3.1", + "author":{}, + "repository":"https://gitee.com/openharmony/distributed_screen", + "license":"Apache License 2.0", + "publishAs":"code-segment", + "segment":{ + "destPath":"foundation/distributedhardware/distributedscreen/" + }, + "dirs":{}, + "scripts":{}, + "component":{ + "name":"distributed_screen", + "subsystem":"distributedhardware", + "syscap":[ + "SystemCapability.distributedhardware.distributed_screen" + ], + "features":[], + "adapted_system_type":[ + "standard" + ], + "rom":"2000k", + "ram":"6M", + "deps":{ + "components":[ + "appexecfwk_standard", + "eventhandler", + "hiviewdfx_hilog_native", + "ipc", + "safwk", + "samgr_standard", + "dsoftbus_standard", + "utils_base", + "graphic_standard", + "distributed_hardware_fwk", + "multimedia_media_standard" + ], + "third_party":[ + "json" + ] + }, + "build":{ + "sub_component":[ + "//foundation/distributedhardware/distributedscreen/common:distributed_screen_utils", + "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_sink:distributed_screen_sink_sdk", + "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_source:distributed_screen_source_sdk", + "//foundation/distributedhardware/distributedscreen/services/screenclient:distributed_screen_client", + "//foundation/distributedhardware/distributedscreen/screenhandler:distributed_screen_handler", + "//foundation/distributedhardware/distributedscreen/services/screentransport/screensinktrans:distributed_screen_sinktrans", + "//foundation/distributedhardware/distributedscreen/services/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "//foundation/distributedhardware/distributedscreen/services/screenservice/sinkservice:distributed_screen_sink", + "//foundation/distributedhardware/distributedscreen/services/screenservice/sourceservice:distributed_screen_source", + "//foundation/distributedhardware/distributedscreen/sa_profile:dscreen_sa_profile" + ], + "inner_kits":[ + { + "type": "so", + "name": "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_sink:distributed_screen_sink_sdk", + "header": { + "header_base": "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_sink/include", + "header_files": [ + "idscreen_sink.h" + ] + } + }, + { + "type": "so", + "name": "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_source:distributed_screen_source_sdk", + "header": { + "header_base": "//foundation/distributedhardware/distributedscreen/interfaces/innerkits/native_cpp/screen_source/include", + "header_files": [ + "idscreen_source.h" + ] + } + } + ], + "test":[ + "//foundation/distributedhardware/distributedscreen/services/screentransport/test/unittest:screen_transport_test", + "//foundation/distributedhardware/distributedscreen/services/softbusadapter/test/unittest:SoftBusAdapterTest", + "//foundation/distributedhardware/distributedscreen/services/screenclient/test/unittest:screen_client_test", + "//foundation/distributedhardware/distributedscreen/services/common/test/unittest:service_common_test" + ] + } + } +} \ No newline at end of file diff --git a/common/BUILD.gn b/common/BUILD.gn new file mode 100644 index 00000000..7dd03dcd --- /dev/null +++ b/common/BUILD.gn @@ -0,0 +1,47 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_utils") { + include_dirs = [ + "//utils/native/base/include", + "include", + ] + + sources = [ + "src/dscreen_util.cpp", + "src/dscreen_log.cpp", + ] + + deps = [ + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreenutil\"", + "LOG_DOMAIN=0xD004100", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/common/include/dscreen_constants.h b/common/include/dscreen_constants.h new file mode 100644 index 00000000..50c0b15d --- /dev/null +++ b/common/include/dscreen_constants.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_CONSTANTS_H +#define OHOS_DSCREEN_CONSTANTS_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedHardware { +enum RpcEventType { + NOTIFY_SINK_SETUP = 1, + NOTIFY_SOURCE_SETUP_RESULT = 2, +}; + +enum DScreenState { + DISABLED, + ENABLED, + DISABLING, + ENABLING, + CONNECTING, + CONNECTED, + DISCONNECTING, +}; + +enum TaskType { + TASK_ENABLE, + TASK_DISABLE, + TASK_CONNECT, + TASK_DISCONNECT, +}; + +enum CodecType : uint8_t { + VIDEO_CODEC_TYPE_VIDEO_H264 = 0, + VIDEO_CODEC_TYPE_VIDEO_H265 = 1, +}; + +enum VideoFormat : uint8_t { + VIDEO_DATA_FORMAT_YUVI420 = 0, + VIDEO_DATA_FORMAT_NV12 = 1, + VIDEO_DATA_FORMAT_NV21 = 2, +}; + +/* Screen package name */ +const std::string PKG_NAME = "DBinderBus_" + std::to_string(getpid()); + +/* Screen data session name */ +const std::string DATA_SESSION_NAME = "DBinder.ohos.dhardware.dscreen.data"; + +/* Screen session name max len */ +constexpr uint32_t DSCREEN_MAX_SESSION_NAME_LEN = 50; + +constexpr uint32_t DSCREEN_MAX_DEVICE_ID_LEN = 100; +/* Screen data received max length */ +constexpr uint32_t DSCREEN_MAX_RECV_DATA_LEN = 104857600; + +/* Screen max video data width */ +constexpr uint32_t DSCREEN_MAX_VIDEO_DATA_WIDTH = 2560; + +/* Screen max video data height */ +constexpr uint32_t DSCREEN_MAX_VIDEO_DATA_HEIGHT = 1600; + +/* Screen max screen data width */ +constexpr uint32_t DSCREEN_MAX_SCREEN_DATA_WIDTH = 2560; + +/* Screen max screen data height */ +constexpr uint32_t DSCREEN_MAX_SCREEN_DATA_HEIGHT = 1600; + +/* YUV420 buffer size max size */ +constexpr int64_t MAX_YUV420_BUFFER_SIZE = 2560 * 1600 * (3 / 2) * 2; +constexpr int32_t LOG_MAX_LEN = 4096; + +constexpr int32_t INVALID_WINDOW_ID = -1; + +const std::string DSCREEN_LOG_TITLE_TAG = "DSCREEN"; +const std::string DSCREEN_PREFIX = "DISTRIBUTED_SCREEN"; +const std::string SCREEN_PREFIX = "SCREEN"; +const std::string DSCREEN_VERSION = "1.0"; +const std::string SEPERATOR = "#"; +const std::string KEY_VERSION = "screenVersion"; +const std::string KEY_DISPLAY_ID = "displayId"; +const std::string KEY_SCREEN_ID = "screenId"; +const std::string KEY_DISPLAY_RECT = "displayRect"; +const std::string KEY_SCREEN_RECT = "screenRect"; +const std::string KEY_POINT_START_X = "startX"; +const std::string KEY_POINT_START_Y = "startY"; +const std::string KEY_WIDTH = "width"; +const std::string KEY_HEIGHT = "height"; +const std::string KEY_SCREEN_WIDTH = "screenWidth"; +const std::string KEY_SCREEN_HEIGHT = "screenHeight"; +const std::string KEY_VIDEO_WIDTH = "videoWidth"; +const std::string KEY_VIDEO_HEIGHT = "videoHeight"; +const std::string KEY_FPS = "fps"; +const std::string KEY_CODECTYPE = "codecType"; +const std::string SCREEN_CLIENT_WINDOW = "screenClientWindow"; +const std::string KEY_DH_ID = "dhId"; +const std::string KEY_ERR_CODE = "errCode"; +const std::string KEY_ERR_CONTENT = "errContent"; +const std::string KEY_VIDEO_PARAM = "videoParam"; +const std::string KEY_MAPRELATION = "mapRelation"; +constexpr float DEFAULT_DENSITY = 2.0; +constexpr int32_t DEFAULT_SCREEN_FLAGS = 0; +constexpr uint32_t DEFAULT_FPS = 30; +constexpr uint8_t DEFAULT_CODECTYPE = VIDEO_CODEC_TYPE_VIDEO_H264; +constexpr uint8_t DEFAULT_VIDEO_FORMAT = VIDEO_DATA_FORMAT_NV21; +constexpr int32_t DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID = 4807; +constexpr int32_t DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID = 4808; +constexpr uint64_t SCREEN_ID_INVALID = -1ULL; +constexpr uint64_t SCREEN_ID_DEFAULT = 0; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/common/include/dscreen_errcode.h b/common/include/dscreen_errcode.h new file mode 100644 index 00000000..7315a32b --- /dev/null +++ b/common/include/dscreen_errcode.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_ERRCODE_H +#define OHOS_DSCREEN_ERRCODE_H + +namespace OHOS { +namespace DistributedHardware { +enum DScreenErrorCode { + DH_SUCCESS = 0, + // SA error code + ERR_DH_SCREEN_SA_GET_SAMGR_FAIL = -50000, + ERR_DH_SCREEN_SA_GET_SOURCESERVICE_FAIL = -50001, + ERR_DH_SCREEN_SA_GET_SOURCEPROXY_FAIL = -50002, + ERR_DH_SCREEN_SA_GET_SOURCECALLBACKPROXY_FAIL = -50003, + ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT = -50004, + ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT = -50005, + ERR_DH_SCREEN_SA_GET_SINKSERVICE_FAIL = -50006, + ERR_DH_SCREEN_SA_GET_SINKPROXY_FAIL = -50007, + ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT = -50008, + ERR_DH_SCREEN_SA_REGISTERCALLBACK_NOT_FOUND = -50009, + ERR_DH_SCREEN_SA_UNREGISTERCALLBACK_NOT_FOUND = -50010, + ERR_DH_SCREEN_SA_REQUEST_CODE_INVALID = -50011, + ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED = -50012, + ERR_DH_SCREEN_SA_WRITEPARAM_FAILED = -50013, + ERR_DH_SCREEN_SA_READPARAM_FAILED = -50014, + ERR_DH_SCREEN_SA_DSCREENMGR_NOT_INIT = -50015, + ERR_DH_SCREEN_SA_ENABLE_FAILED = -50016, + ERR_DH_SCREEN_SA_DISABLE_FAILED = -50017, + ERR_DH_SCREEN_SA_SOURCETRANS_NOT_INIT = -50018, + ERR_DH_SCREEN_SA_SCREENREGIONMGR_NOT_INIT = -50019, + ERR_DH_SCREEN_SA_SINKTRANS_NOT_INIT = -50020, + ERR_DH_SCREEN_SA_GET_REMOTE_SOURCE_SERVICE_FAIL = -50021, + ERR_DH_SCREEN_SA_GET_REMOTE_SINK_SERVICE_FAIL = -50022, + ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL = -50023, + ERR_DH_SCREEN_SA_SCREENREGION_START_FAIL = -50024, + ERR_DH_SCREEN_SA_REMOVE_VIRTUALSCREEN_FAIL = -50025, + ERR_DH_SCREEN_SA_DSCREEN_TASK_NOT_VALID = -50026, + ERR_DH_SCREEN_SA_DSCREEN_SCREENGION_SETUP_FAILED = -50027, + ERR_DH_SCREEN_SA_INVALID_IPC_CALL = -50028, + ERR_DH_SCREEN_SA_REGISTER_SCREENLISTENER_FAIL = -520029, + ERR_DH_SCREEN_SA_UNREGISTER_SCREENLISTENER_FAIL = -520030, + // Transport component error code + ERR_DH_SCREEN_TRANS_ERROR = -51000, + ERR_DH_SCREEN_TRANS_TIMEOUT = -51001, + ERR_DH_SCREEN_TRANS_NULL_VALUE = -51002, + ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM = -51003, + ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION = -51004, + ERR_DH_SCREEN_TRANS_SESSION_CLOSED = -51005, + ERR_DH_SCREEN_TRANS_CREATE_CODEC_FAILED = -51006, + ERR_DH_SCREEN_TRANS_RELEASE_CODEC_FAILED = -51007, + ERR_DH_SCREEN_TRANS_START_CODEC_FAILED = -51008, + ERR_DH_SCREEN_TRANS_STOP_CODEC_FAILED = -51009, + ERR_DH_SCREEN_TRANS_CREATE_SURFACE_FAILED = -51010, + ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN = -51011, + // adapter + ERR_DH_SCREEN_ADAPTER_SESSION_ID_NOT_FIND = -52000, + ERR_DH_SCREEN_ADAPTER_UNREGISTER_SOFTBUS_LISTENER_FAIL = -52001, + ERR_DH_SCREEN_ADAPTER_REGISTER_SOFTBUS_LISTENER_FAIL = -52002, + ERR_DH_SCREEN_ADAPTER_FIND_SOFTBUS_LISTENER_FAIL = -52003, + ERR_DH_SCREEN_ADAPTER_BAD_VALUE = -52004, + ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL = -52005, + ERR_DH_SCREEN_ADAPTER_PARA_ERROR = -52006, + // Encoder & Decoder + ERR_DH_SCREEN_CODEC_RELEASE_FAILED = -53000, + ERR_DH_SCREEN_CODEC_PREPARE_FAILED = -53001, + ERR_DH_SCREEN_CODEC_START_FAILED = -53002, + ERR_DH_SCREEN_CODEC_FLUSH_FAILED = -53003, + ERR_DH_SCREEN_CODEC_STOP_FAILED = -53004, + ERR_DH_SCREEN_CODEC_SET_CALLBACK_FAILED = -53005, + ERR_DH_SCREEN_CODEC_CONFIGURE_FAILED = -53006, + ERR_DH_SCREEN_CODEC_SURFACE_ERROR = -53007, + // ScreenClient error code + ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR = -54000, + ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR = -54001, + ERR_DH_SCREEN_SCREENCLIENT_ADD_WINDOW_ERROR = -54002, + ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR = -54003, + ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR = -54004, +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/common/include/dscreen_log.h b/common/include/dscreen_log.h new file mode 100644 index 00000000..b8c92965 --- /dev/null +++ b/common/include/dscreen_log.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_LOG_H +#define OHOS_DSCREEN_LOG_H + +namespace OHOS { +namespace DistributedHardware { +typedef enum { + DH_LOG_DEBUG, + DH_LOG_INFO, + DH_LOG_WARN, + DH_LOG_ERROR, +} DHLogLevel; + +void DHLog(DHLogLevel logLevel, const char *fmt, ...); + +#define DHLOGD(fmt, ...) DHLog(DH_LOG_DEBUG, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGI(fmt, ...) DHLog(DH_LOG_INFO, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGW(fmt, ...) DHLog(DH_LOG_WARN, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) + +#define DHLOGE(fmt, ...) DHLog(DH_LOG_ERROR, \ + (std::string("[") + DH_LOG_TAG + "][" + __FUNCTION__ + "]:" + fmt).c_str(), ##__VA_ARGS__) +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/common/include/dscreen_util.h b/common/include/dscreen_util.h new file mode 100644 index 00000000..8b113e52 --- /dev/null +++ b/common/include/dscreen_util.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 OHOS_DSCREEN_UTIL_H +#define OHOS_DSCREEN_UTIL_H + +#include + +namespace OHOS { +namespace DistributedHardware { +int32_t GetLocalDeviceNetworkId(std::string &networkId); +std::string GetRandomID(); +std::string GetAnonyString(const std::string &value); +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/common/src/dscreen_log.cpp b/common/src/dscreen_log.cpp new file mode 100644 index 00000000..ec34b603 --- /dev/null +++ b/common/src/dscreen_log.cpp @@ -0,0 +1,87 @@ +/* + * 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 "dscreen_log.h" + +#include "securec.h" + +#ifdef HI_LOG_ENABLE +#include "hilog/log.h" +#else +#include +#endif + +#include "dscreen_constants.h" + +namespace OHOS { +namespace DistributedHardware { +static void DHLogOut(DHLogLevel logLevel, const char *logBuf) +{ +#ifdef HI_LOG_ENABLE + LogLevel hiLogLevel = LOG_INFO; + switch (logLevel) { + case DH_LOG_DEBUG: + hiLogLevel = LOG_DEBUG; + break; + case DH_LOG_INFO: + hiLogLevel = LOG_INFO; + break; + case DH_LOG_WARN: + hiLogLevel = LOG_WARN; + break; + case DH_LOG_ERROR: + hiLogLevel = LOG_ERROR; + break; + default: + break; + } + (void)HiLogPrint(LOG_CORE, hiLogLevel, LOG_DOMAIN, DSCREEN_LOG_TITLE_TAG.c_str(), "%{public}s", logBuf); +#else + switch (logLevel) { + case DH_LOG_DEBUG: + printf("[D]%s\n", logBuf); + break; + case DH_LOG_INFO: + printf("[I]%s\n", logBuf); + break; + case DH_LOG_WARN: + printf("[W]%s\n", logBuf); + break; + case DH_LOG_ERROR: + printf("[E]%s\n", logBuf); + break; + default: + break; + } +#endif +} + +void DHLog(DHLogLevel logLevel, const char *fmt, ...) +{ + char logBuf[LOG_MAX_LEN] = {0}; + va_list arg; + + (void)memset_s(&arg, sizeof(va_list), 0, sizeof(va_list)); + va_start(arg, fmt); + int32_t ret = vsprintf_s(logBuf, sizeof(logBuf), fmt, arg); + va_end(arg); + if (ret < 0) { + DHLogOut(logLevel, "DH log length error."); + return; + } + DHLogOut(logLevel, logBuf); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/common/src/dscreen_util.cpp b/common/src/dscreen_util.cpp new file mode 100644 index 00000000..f404d41d --- /dev/null +++ b/common/src/dscreen_util.cpp @@ -0,0 +1,97 @@ +/* + * 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 "dscreen_util.h" + +#include +#include +#include +#include + +#include "softbus_bus_center.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +constexpr int32_t WORD_WIDTH_8 = 8; +constexpr int32_t WORD_WIDTH_4 = 4; + +int32_t GetLocalDeviceNetworkId(std::string &networkId) +{ + NodeBasicInfo basicInfo = { { 0 } }; + int32_t ret = GetLocalNodeDeviceInfo(PKG_NAME.c_str(), &basicInfo); + if (ret != DH_SUCCESS) { + DHLOGE("GetLocalDeviceNetworkId failed ret: %d", ret); + return ret; + } + + networkId = std::string(basicInfo.networkId); + return DH_SUCCESS; +} + +std::string GetRandomID() +{ + static std::random_device rd; + static std::uniform_int_distribution dist(0ULL, 0xFFFFFFFFFFFFFFFFULL); + uint64_t ab = dist(rd); + uint64_t cd = dist(rd); + uint32_t a, b, c, d; + std::stringstream ss; + ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL; + cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL; + a = (ab >> 32U); + b = (ab & 0xFFFFFFFFU); + c = (cd >> 32U); + d = (cd & 0xFFFFFFFFU); + ss << std::hex << std::nouppercase << std::setfill('0'); + ss << std::setw(WORD_WIDTH_8) << (a); + ss << std::setw(WORD_WIDTH_4) << (b >> 16U); + ss << std::setw(WORD_WIDTH_4) << (b & 0xFFFFU); + ss << std::setw(WORD_WIDTH_4) << (c >> 16U); + ss << std::setw(WORD_WIDTH_4) << (c & 0xFFFFU); + ss << std::setw(WORD_WIDTH_8) << d; + + return ss.str(); +} + +std::string GetAnonyString(const std::string &value) +{ + constexpr size_t INT32_SHORT_ID_LENGTH = 20; + constexpr size_t INT32_PLAINTEXT_LENGTH = 4; + constexpr size_t INT32_MIN_ID_LENGTH = 3; + std::string res; + std::string tmpStr("******"); + size_t strLen = value.length(); + if (strLen < INT32_MIN_ID_LENGTH) { + return tmpStr; + } + + if (strLen <= INT32_SHORT_ID_LENGTH) { + res += value[0]; + res += tmpStr; + res += value[strLen - 1]; + } else { + res.append(value, 0, INT32_PLAINTEXT_LENGTH); + res += tmpStr; + res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH); + } + + return res; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/distributedscreen.gni b/distributedscreen.gni new file mode 100644 index 00000000..217b56cf --- /dev/null +++ b/distributedscreen.gni @@ -0,0 +1,25 @@ +# 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. + +distributedscreen_path = "//foundation/distributedhardware/distributedscreen" +distributedhardwarefwk_path = "//foundation/distributedhardware/distributedhardwarefwk" +windowmanager_path = "//foundation/windowmanager" +mediastandard_path = "//foundation/multimedia/media_standard" +graphicstandard_path = "//foundation/graphic/standard" +common_path = "${distributedscreen_path}/common" +services_path = "${distributedscreen_path}/services" +interfaces_path = "${distributedscreen_path}/interfaces" +fwk_utils_path = "${distributedhardwarefwk_path}/utils" +fwk_common_path = "${distributedhardwarefwk_path}/common" +fwk_services_path = "${distributedhardwarefwk_path}/services" +build_flags = ["-Werror"] \ No newline at end of file diff --git a/figures/distributedscreen_arch.png b/figures/distributedscreen_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..e4c0deb8bb27e9718ef77cd0a9e4736e5d53ff66 GIT binary patch literal 24264 zcmce;1yEdD*DcyWf@^RO1b3HU2_cZi37VjR;O=h0{RFq*uEE`c1$U=$_r{&KJ2~Hf z|M%+Fty|AlkxH@Yz4wy2=9+ViF*`(2UJ3)11Qi4VVSqnKd<20IPCy_y8DvD@itUi` zci=x1n-8DtK_JXd*gv>l>w>Q!&`S_l;;o8H>H);lL38Q{`~5K|*SmSn7W?v!NF0IEY#2%LBY-f{}Xov3jW&|IO$GcPXHRR4~j7GG1w;& z_23o$UW|oHY{&h3)e!W*^HC);Owpik`)QqCAb~SFtF|L0fsyccEjW(k?>ilxGgemw zCWSuFd-Y7B86Q6DO;RCC`iiQhNll%F-u)~sIG9c=VP6SvvNfd4bcs$*q!}wX*yJ^5 zju42Nx?hjhc^$IutkBX3>w6y6Fwiq4_|xcZ_)Ue*yX34L+H<6IG)ncKj|?Ear&}Q# zgMHJLNtt@i`-aAItS;x7%HRvGL$S8FxoB7Dvg zi^_}<7&tg%&;HDs?fI`yO(^O77Vnp#&ZEvA%w@vl>!t_X)@zqj5RI#8q0@@G>s4U{ zmc?sKQL}pZ#0FGKa&IJ0(rtf*xrSThR_A;2b8>GyG{+(`HsHD@f&TX1Mq1sBHFpua zb?L9|)!UCd`BtfI&(fmT9a!OCTrGI&C88myo$4JwCW+)rE z=G;`?KK?wwz*=31&oU8MVr_8D?D?FK}?=2t*M81Lt&fbVlGV4#e$nkv{5a(sWb&d5d}QjHCDq^AZMq z)@>P6gl^gP*^y2L6V!IBv9Sp*RTAR(-9EpHAa_=Qyy9*QFyeQ!4$^mX_!=bZi(R&O zYyCD^3kV*@Z2i(Q6=x6GCalo)vn18)yJ)3aQUeQplI{z6iPqYRy||cNxns)r=2K(` z-rizHtn*A!s;Cv=Mdj*v5w}agh9^;wT?q+h$g3Rx_$EnCp2@e+4bQWeGA`lm@&z`D z^zz$%hGbEGD@swB@OsRh; zo5fP3r#N1vxpd#@8CMN>1Ey88xG;F~^%HP?AK|fNG9SUq2Mu4inATaCy@+Qm_*F7Z zZnL!3yU;|q23=345$V%dyW+jL3kCKhmo1724ob}I{_fx^wWWSC>S5J}b{Y9>NWirY{>u>w1fgYhe%k#2d-JbaujWf&%gersGh-87 z>)mq7V$bwI=J&wf;vWOW{6HO9`5dqfH>5N{?SKVoPzJX8+RL;#XA)+sBwTHS)59K; z6b*fyVR)y{KgGed?6 zI$-`#Kf~!!X~DLZ*^hU{@$3EbLW&vjte=8J9TBUGUNHXz>(n-XCBNmPtDAJ|re68J zf20_#Fci*(y6R$vztn1ui|T~Xj;}HE6MK}6m~za>LDvUgbLp*l(Sz*!DZ7%C8%39f z%g{j8!~hq~M0y;lJ}s7Rnc1A-+HCAPR(QS|wyyP6D1~{`d_@R^|6%_}SIyg0bJAnc zZf-2PRGf9fIBfgPXuh82#Tn$6|Auo0}UXv&YgC68QNc6*<&mV%`m7Cg&-# zdEcNretln=I7lMA`>Sn#JN&nqaE8r0(4@!bs*J@D6=RPCdh}nPuj>Cf)`0GfGr^ui z13m=31do@swzitd&AEZ2`5445NzelYw@1<`d5F;OXu$I*D<~iiB6NGuOCofN=ZeT6 z@!&mQUtevX<_*nq7Jh#IUOkS3f&TtmM+Q7M#b_F4ANF^dqn6THq*Uze)>dk2)1;Y- zCUc{sqlEj}{`H7HbGdK^Ss*B-5{8lI!16FUa9 z;CWhqqOqVV;}NeC{>S7q@4{WpLB5Myd~`%e|LkpcIit_}4n3Q(2K#Nqi#2*rz()Q= z38pc?RH;YjOe-=tyz};Mqw#l9@+@o2$jH!+&T;eWP@G*}W)Be0H0;njAsO0LAOgnw z@bK^+HfHo^@a1S!^RWij|Iifj!uk(1`4X-gYAT6h?5xbTHr;3%({vheX+uMUAlPXg z#jk^d9vfMU&3^|4(XRy2}_kEMWfQPDD zgh4YAq|u8A?>q1=^Pi(|_hx7mi2?7D?tV?-OgS;P(FVu_UtFc=fj>$1c{I%wf{Ed2 z+UtJ(ivXc~NkH{RY)t+2^Sg$);3i5N8?{>GzK^o`CfWO=zwK?ICEmKRTqj@U#4 z?w*^QvjlPQ@Hj{#kG%p%i|8cfl^IVFUu9-y8q_jAxS$IEZsTpbCIn{KSkf%v_W zh#Iq6Tdcj??wH61Wz(s>8qjP z1Dww-ZHFwC#K_Irw!x4z{Y2171plq$~UINLdPoDS^JP)RW2G5WPSfOlvDm!JrGL9W(lJ~GT6{Y`uk6@ z(9sWGJ0C5sw70)81eQijNa#)`dyIhwY=-d+Ug~@gdgI{PVDUh18H4{w^%l&*iGF#?S^%r4JIIa_d)EjvGw*+Ja;nuOesXh^y8n8Y ziy9!_1o9B%;W-~P>5YPU|M7!^Vg>!qJ2i{ziyyyJdMtGuJls#l&)Om7t$~_yyO@E1 zPzhFKb|QreLn!(GO2YnC665=X(_>B z{e>Gf34*KOU1vY#44jq1OWyRpIph&1gOUUWGUV|8STcG3*OzQPUJ zyjHTLjJy}tN2xU`Z175f?#Yaf_-{P!Oz$uFrSI1kawDRwT^}%7>c(#FV;yyTIvg>( z(O8iC+57-Z*xD*D5{RrFt)D0#FFoFF`Tl| zqg0_a5Mwz~XPAxNY>Ah0eKktw-4DCR2iJcP0|<0 zJR^oz>rS?|(N0dvr*Z~@HNC4r)@31%;)J*EphVCh@H)DJ*6Z(0zff{1_9r?~=(ivN zP32}pWn!vho}5EH2gSAP6H&Le=C(x-;YYp8LAVg}zs`NVOS)c9~ThzYHth#(kqW6`~wY^9gXzYtb4ScQF@pyNIubjj- zh|l@OX1vq_=QxMu$bxWsieuTqD@d&(q^{j`E?5p3W%YzD>Yplp^Yl9zgv*&lM<{G* zPrz%bhG7(XfPp|Khlq@fWx3VU9f%T1)N5*LHh~z$MCCM8u6?_+st;wzorvAz{AcB} zCb+USs1^Yv>T$&P7p1AOO-zEi1$t9?=dqA%mL$seO%*+KwBVlnpP~@d^#P386BQ~QmvOGV zcv!HQhi0WOC6Uc-%~m4dv)oej>9m=y=g2BZmuTsFkcYIYoP=$hF0b&UwFCk>babfz zZJvQ#^9WBU6!|6gd)?WkdU&&jTG|X6+#fx#X%OzvcYte1%`HC0e)f=Dyxo`7xT@W;wvqxO7Y7`D z0O!d5`W8}L(|(50f3!iFeZNaY+BDRJ){`)$JxF?D^lAO%peZ`B)n*;*qx57+9f+N= zDa+briAOja{gsurZrEB2tF-$Q`r-@xnP9%`yHkWzjg098aWQ4iW41-lxEGxfV(lT; zGg$&hDB!Ly$q{oq;tHQKxl$~BYKM;Zi^v09N9H?pA9z*U{?ty1^pqu(((N zrOA5{)=eFGXepz4haa|IVWn<9KTn@ku~6L%w|npGAIw0`L@<+`oo&#+K|m1p{)E^i z*~-k^To9Jt!dfg!eF!-o^~!9P92~KJpnFiyZTs;U@Xd3veG|XuxxzM>^mX;R@NE@RadZI3o9Q_CUKf1GsyL_df32k;8O(k#r9F$$>jA)!CCv3T~_1o zC?_fMM)gL;#!}2-c@RhE>NwrCPW5c^ikesD!l4rDfaC9NcpvhiG)WERkixN?t}%3; zLd(93jP5|XTwC`lBx%*tY>=aT!4PHw?O1-|w&c|edQdjHJpC_E5>AR&^Qw1xGpX5~ z3-Ajzy|J9p`+r84c+srMQxxoJ)PBFT40eQkza>4I8Q`rG$NmDae$j#qJt~ zzOeD`_Uv2DqnBK?uR}BDmQc30E^R~(Bk3FjwN6}wPh7MZ4(-f`&#~x(C~iCwveD%F zxlapwHmqLz-$)B#R*}l_kzx+1@AGy-c3#*zTS;# zOn<;!tc3T9z&u-ci$iGT)FpO9B<_*EHPG$fD0}Sd!1TT6I>S>lu__h~m?V~FR~14~ zdiLd5CEDN#$E9CQzZ7HV63&M(Xwhhv>0)Lmh1|TeYGRrMY48W+AB6=t<9u@FPURVC zu7Z#KDZI)>@28l*1d#?c7xsR&R*PApR+-<}sE{mdEEq@RZd_50es5kQ9EJtrh?9)% zK2&bDZwXqFTzd>02xI!f?flFBYyFq1Y&xekicDocxkDVCB%d2L0X`b zCuFL zg{CB&?hW8MgwM*^UO5ZuQ3Tn??3Fj>Xq_3W^wrgHE{di)8o2PLIyD>2XsVd{&9z`0 zE;(7)o2wJkP!7~ziXp=MF3(%H)x}22Dw24EFEFqs%QP3j9<-u!2C6D6lZ9Ttwu_<^ zYZXd53uUt8aJKBMWh32)+og;BuCK5|2DBWls<``*X>3~2NGN1eUC(;V_( zvb;rM+vvVBkfL~DktwSzm3J-5oJFd%+AwO{A6nbL;vK$ zxhdBVmC>Nrm%qAt;};{Gqn1UWoWTCCwpr^6!Cihha<+fE?iJJdu-la-J-gyxWs%EO zrR^_Gy5cZjVW-kii66m+MCR!DQxL8_a?40)Q7+j|fm_d9+(or!4rj^GOJD!nsjRcM z3u7H*)rUCER)9a`Q8JdfsVIv2@naAMUyY7Cx3C(BLHyz~lCa~ROY*ACEY8EBKLpXD zb}lxGw+Yf)qHgNcN^axap_Ki=F)TQJ^D`Sv!E8u)YrE@BHZCyzJ{HPC5GGJt#|rr} z%2V@yIe<7P9q=$_EPu&w=KsO>@L#g0dm-xzSL3T&c_OFC!vP@R)wI1$ECW)yD=q*n zzL1X;P%p#PoQ5mD*b@y6+;>{(x6!W9C#v;+ATQ{AeQueWO?ed^FxxonnM_0kZ4h9 zqCw)<#pM0K0`tX9H$48MVi@o%nRI)WZoUDq7No}{I7;)XEM-za8*d2c)}I5p(%&eF zA*5$`Re0WALd)VEB-(D-V&pDbC#R?FfF)Hj+6}03!WFfi4Q*XN&Nwbrz4mb2sDcQo zKfQ3-gV7R5WwiMfyM6p)xv__0AYpGUw*7@lY$0_i(Sc_B3mgyjEUn`PXcs3)3fcrw z*Mk%Z-fojEhcYYlx`f^WD72>||8z@kmu;As*40LLx&+JqaeG8*u1(=#i)#2pvhhfe zfl|z^hGpbo@?MBA#cYEk&y|n-qSB1zDl3}rgjep7&b=2U2O1L8o%Zs7a2hT%K#)oI zosc!sX-L%jbborVwx2QSBv0~euihc(1rl(+XUW>x5c2)_9NfDfYq(2mU*WK2+U%LZ z@A11Nkp5Ry6`FeKuM%aE)eXxpKZLoN(lx_B?ev(+eXQ0W$nG2|R%h*POv;D8cNmYA zK!+jPf>o$>aa{sP0XD*T$9*nxO{&gVSH{t63Pb}*{LsN8=ATEba_+Rwota5gkuH~F zIw=Otd2T&+SX~i9w~eZ*`rVAQU&PKhms+zBN7%n{>6|7A$PmH^8vj3o3Br#s-`w2g zOTpmV{Be@KkTVn(ZzGZ{hNFuui)lSzqf63jyx@z{X$+vTTp!e(`F$n|n%L|v-KMiv z+jLb)_LJ;g3o9E-K07^+?-BTX;p)tu0hYz>9SvJP7K*^f5+RhI1t<;QB-Kt7Enyh7 z#wx;~;fdq~pE&gs|9Bc-UjH84WtWFUuN2zrm{2iLJwpYIp(!t9Au`qlU8;-xsu6#! z|0ID%q}_QdtE3uFXjv?D`h}Qi`lo<4c4EV(KAl%UfTsm`b+@A4OloElk@Y)|Ym-l; zA}6u|Z=zv{F@s-hTs%B?P&#L1te(@yq^a0+_P|qFyXLEii?uN2c2z8V$w_iCL^+}4 zoCe?(iblRM(rd*O0JkO;M?@+9Zdb^po2ENmmIcNe`3ZO;Y7o(fC=?C(LDz`4iMR2N zeY<8#0m!`(K4nQP^f;4LMjaoXHcq2rD(V3Vb8Q2k_tZ7plt0cK2+|zB!-C!{*^dCJ zk+1XXRoQBn)zj@*ON{%IOebk*VfBc#bAyu}J;9p$7-U zigGChGuvX1902Q5HyBdJdE+#}LkILonfTA@_Ww8DVpBoQ!WF5sFZFW`*}jn|o=$vo z))#yuDz0^{3S^g!MxodZX>NmL3-tb~Rhi{bonPdh!{YU|EM3D>x3)T;+>uZxD{1#f z)t`f6u)W7C@P1W1kZV;uVlKKsWbEb!Rj(Pg0(+tJWSzWnsxPkI+}AsnY5q^hi@gMT z11o3vUVi}a_dDUWlOXYkAd}01x<@Qd;zQ>-sHq!GV3%>D%D=y&&a!pDds-xMpW}gr zhY=XCXk$zu$!~i7I7bK>mT#Db!5A9coiMSh@WNDJGY5a@CI&VwiX9cU#6z;~TFP>w z@7+-=Mt;*Kd5wbem42`0-Kv`b<>T>9`HE{P{v6_?y(}!$hC=xzVfUHV!d-bj@!cCG zkZS69kk19m{Bt(5-2PqRiJX!`F!I0xfui{elkOOHPb?mcBuRebt?o|$xL01u$;0Dc z-rDNZ(ccc4{Ersk>6ra`ZyyaA#dm=1j=AJ>g#d&KfOK$_0%5!_Psem=*}GwWV+oJT zndMa9i>NYLW!SSNVnbkoqTJ6EW>yaTjrSgE9}|O~^T*~h{zSDM;vNtPjetc! zR6yW&O)Af>ot>RLnSjkoqeCyJs_=D{vCVze$OJi}+)t5X@}9IS%zPnqU{^|(HC-~@ z-x5aU3xzYjqNm@Mu(V`7BTZI=-A@G4v$6T=Zp+{&PQ37hju1oyh4wS=}#b^LPp zwBNeov5Dy&80gZ(3s?%5#n8frL@;w8am-^K1K1E(7)%HOL@LSA__KEU-IK*(z*Pp6 zQ~;RHGL_UBZq>M%xNXg2a6@_M$nWfB)j56+@@RfEniRWxZqpxfd$KLstYpvq8LP+< z=!9d!x>SuP$LU!x?PW6U@vUV~G5cGw^|9TmqM1!1HZ=C$nO*myihzO1#*L@`&GqvS z2tY9O{*SIg?iKK)Gnz(9`!B~KSU<1)(Yl{jr^U{JVLkSFuld%A{S(!ai)5V&w`Fw? zvW(J38Fa`v>_VDt8Y2A|DT~JdCco}cI%ZaVYQ;Ax`BoVp zk`OJeGIS4*gmo=Broj3`G<`0F+*&sTX=%Dkw-SD!C~zcn$DOIdbl{gGZ$Pix5fjqm zr3(K&SQ3CG95~lud!5Jf-06v)B&m?VH z3eI&{1=1c`)k{ZD&rY86#Y+vBJe7)cdzp3boh4b_Beg~(3+U>Z+@*2U5&`T5Y|EU& zHr!aXlE$s&o1`ID*)9Jf-dT73h~{b!Q}WL;VsAQO)VbGrD!eo~ogUuVKtS#?qR~=# zEjhE~<)&Wf!{qqBJ(%&4fU?~iF)>9CU;JZ5Hm=@joLkMPU#_ynRh6oKRw}tq{BmG=g!Ny}F2VJBUOXleewHk)NTY2dI+H6;7 zU>&(eOEqR#`g4%b^izN2l~m8@08 zZK+d6?!D1HQfzH!3MA?0!8RtD)-4S|8wN;y&A0cUozYTw%u@2|dHsbtWd_xh7u}RG zZv5dj=>5L6q-TRNTgvX6g-8wj+!rae;ehG%h{J;bT&mW3IqgVehgwBbGb}O^6I@;b z;25O6k>qy+UwaHHG`cEUEMw-r`iFL3xIiI^ZJaQ4VApNsk|gKOIZ>l+Vz)wrg%nhR z^s@p$usS8W-}69ZvuV%0s)Z~}pgl}hL7iJ~?sBZ{_uq%H%4_AAUmnbn`eS?IV#CbB)-H>~9@)`fZ>Gq?Oz+UQ( zirG(o_fZq_GPI#R=-4JxgO0JWN&^5nyvDL%qc4gpG=+6~*hWTL3)(mVuNk9RN|Yv9 zOvffiwnXro(sX|!^1aI9t3BR6PX^_M(XQg*vi+_#%Zj&;1-OoU+rdOqwd9@{fxU36 zjpscs9;zxT7P#Ubly4%p*2`(YpY!#5X&bF1aEhxWn|DIe7a2vVgb^%Wp~w<;L|y*ZN`Y~O2d8Q( z7{>Pe7IJ*`aEat>0?K_Wj=ybti`3=wegNo8_2*TQjlj9B=(fcVR0O~?-_R#p90iXI zK@n>Pc?wBa$c3B^qyXaju^Z3?Skr>J-gzNDa)F~U$$&rTMi+MKSAb57Kh%5tB~9~k zQBr)_x#Hm5s+OS)Roz1rSi-;$8`7Yy!bxTmcVCXSjIogz<8+UWmd$j;>XeO=ZEryx zfKFAplg_sQ(>Psb^g%Qp0EhIP+H)fdPmN1-MZ@b9#2(JW)_bEyPy)o61F)YoqjTN> z3I=M3E#MY_CWnt(=fCut(y6|J^?uC}258tSgls`Lo0ER@x0I5bMf?j*6pE&nvb=J( zq9~K`L=<)6VC@9kDbZT2S`)}J@FEu??$;|kER+^k|cJlgg=tLu~ar*U2q4_tmT4Kx~^08&%u5clv7U`<9L!TzJNRq=K z+hL$@G1t20?(C8$t`RkU+ zP0iDREyOi}P&e}u($<-CDg<$PIFfXzNUEnjKgsIO{FGJJj5uUboEjgp)1|0GUT5d_ zH*5y{XLE?Qc-u6Rl*`=p^}(WO#m1*c9EG1LxnAQ~(@s3n^^~T0L8!4?28yR+&p}#kzl^#MB zPREE9?v5uhG1~4 zHH1@(<@2<~FT!-sv?C4^lE%~d;?e8#Mx`GEchPkHCdV>MF+55=r`EJM-}^xzBuuh; zHi$3wSl8`Z)d;j0k^*Rb<=%;X;=0xS;Ho<=L44@h=MLPc@mNYj{qc`z4>qs=w-mm_ zwEs;B<LG)0qBDme8fTj(3mD*Q){Kc1XuvO0%(?yKvWVJ?d|Pl z-@biwqUy2({T?2Etjx&JQ`gnibu3vor~zKrrW2im(I3@<==UXZWP5*LXlRJ@kD{uw zhj9TARncDR0NNpA6O$c5UbdP;l_>RI3FNVio;2WA0CZIY{fX0<&`WhE~dVD zdD4iTRSL+LP@lmk1c_$`6EBsNl=Q!OsW=I!p-`xbXu)PM)rqI4=ahIbhB&hIOYHjQ z^78W6OHj8%LOi@`nP?Sj4kFaMySrRPhH4ffbe(LlD4?5qi2kUq$w4GcqB?^M^i>|X zPYZbr7ah?Z=rP;oHO6bpd^Zm*@nAJ7i9d2I@VF>A`twD6Q}5okNsqewVKi~}R|A^= z?4*GIE?KfUT5Na=DxEjDy}Q$l8=>;wf%5@)t3>^&qywm{tE+tgb{tG>0!%Q%2JITq zo4d(+wuX&psj2lTA_U)d;R|jm2|wV^%JU2K{wIijZ|gp8MOq0>t>fZ|3l|R?VPRm1 zyaJCe4<>THq85yt8BytB{)}o6%OM&4AN!Ou*243KV55lh@UEtm<> zM~1y+GC@|Wzw&|t#0^(}u{Q{4WQzN2xIT*L^cG4Wb?qA$t&`HuaY_@t>JvanUxn!_ z0Oiq4zMVWE1abqEGap?q0#A!DGw*N8zv`lOsCxh@BF-4mk7$}gf$8v)*8|0$ZUKo^ zB8oLrFMXmV1vDV)hniS4>yVOu~tT7?odz-s6CnEhkI z?=AzbBve3~1E|TEM@of-a7J=Z@bPvXEtEy#b;}=JiF?P%N0E&yn&e3hMB----~A#L zAQrj%xpg}<3*n}S!-(2E3tFpDkK!#)B~M2Lt8a*~K85gZDL*}KdpdIV``^7t%n|6l zSvKuw0pw0Wa4)fuClNZ^QhHuLM$53dlKEU-_0{WwcE~9C{>sm?A0Xl$y||Hv>I_rAq+@P$T@zk&I(d%g-B+w&rO4+AacJ|46!+8q+UHYoE{%}p;M#``rs8+(9hdT2j_fudgA>mj1ws-E zZjuP`xroOEGgl5GhvJkL;s{B&45VaYecljsK<@Ya`SZh&$eI6z9tsdYrFZBhzVa_n zQ7?kmz(YqQjIix<|2X_Zh@ZjV1Y4YiizI?tNN6EFF3#~QKx*y*_EKER4>8~&hZ0{u zi&f{WMmXJPsup72YcYE3sqMFQf%Qj@`Q~m9?XZ|BOE(PXfhpvxZt*`mE|$&xPwh?@ z7Z<9%?llN6t@V@?6>T

mba|eoPFG_G0ySxm;|p_q(~d!Qsrg!>8mSK{$CRe0F7> zmV0ACK=CP|)+ahPi1s4x+HwJO%YkNai&*G_llJ(vi*V4ue&M3tbb#XEag~LIaoS_4 z3hU6FNy%dy$A;SURJFvsGrn?2L%R-3Q!7mIAJZ$b4k~VmwXt4ASu1_B1Kk?n;lFynita(yZ+E6<*wFAt=y@r$WKMwhe-d?0 zw%$_Xp+a7QKbphNhMgIGlYz<5kDjICCF@AQyHKf$sOWbB<~Kyfiphb6XQS#m1)QT8 zGF95ty}^s6L~2O+bw-5%!gA8J)OkzgC*zPD;k(oO%orEZHTw(W7TUIo{>jE_nN4MF zwj_(Dl#08!grIfu3Lb8^hR5H;3thJH>w!WeD<>VlHwQhD#NgD}doad=ma(SR!fDdU=kp<;ZI zRGS(VOd`m zW~&68LC%0j7d7PbYN%!JH!dA*-pX!k6T5fb6eM*FX+6pwETmA#=0sc8)&4dWHMQO; zmudhJsb=mh>1@vY_^g#5P%3#8Pm`4eM*j)}r6zCss#yi6ElBIC% ztIa-ed*#sVL(gXx#z^(N>8ZfGWs}Y_{ai@R9mhh=2jjp8nl$eN`jTsR;=ZY7*Z3nC(-*~AU|jd^W+V|WIYG*T3A2LIWF4B7IsuQ_%ei|RrJx@yQ&@r5IW8(Uj! zTtL`RSylCVXA1WY-tD8*R;hcGbptFC!L8 z`2L<+rPd8c5!y5tL zo0AGR4`dKS$AfkC>i4y;^M~z01zjUY%Kej@S5dp@lJ#k;x)NwdO}PA)H-z`Aqfx)w z$mm0rN#ETuhbh_WQUJ5=hjrYn{75TMG#7fuBlAuMRWVRubOAvHkKT%XtHJoixzJK# zKzY#Cyu5Of!;|^Qx+iaoVZSFa|FFt&z)hI#)0BA-fT>OTVwJZdX>K6|e_ik%TK|(h%jtiBC`wpuj^?n( zOBzspAEH0N4$W^JdKK8>57c^!cZS_C-MAdxga{Dk6=1LN4#{7>+8ZBl{q}47?1ItY zRW1D9pTi6I>1t6n1WC_X zLI=+G#_cDnEM2}n{+|2gf2iXr65hxwIWERWnOE%FX*>*n789nNCz|gK?|BusKCztM zA$Rf0c>Gt@qxZO%+Betabp1NQyG4lyim3hX-`x;L{ay@)%^tIIA9)i4-c$Fa2VGH?ff2tswVXEeP8^S4(}QpP&R-qn>A?k-&^>`lNO-%Pc%0OR(5m z0}-gU11zATZMe7geWTYk90fbF{W|oDJM>)8+a*CjDM2Zs-)aI#KfXJ;k3vD(Vy~FI z$oGW#wcEFj3{CKsee4Jy{CCnRFc1uKCC$T5x6cV~C3aei>K@2cS-Nj=&d@+V)=k9+ zf4#C^^h+~LUztdIuaU)VPN?t}Ol5O%(U15=3A3B=omqKnk;aw5qQgU*-T?Ea%WZ3O z*Wn}Bn2uZR{#7Ko&#}TATTh*STm9DO{34g^*Xb#@CseUXIXF;8Zpppztu#-Ks)Lw~ zy(s%KFWtay@+y_Pq_>d|TaFHp8w24|cQNChhmpHI{TQmN&0qoL@}`VEw^+;F_6o;# z%FEc_QGpU+6HnJylsHOT>vT@G499d9iaG-)FiEpFpbl1Vo?+RU!hP6710pp4{}M6p z7-RvPa}$u{7jMEuvk)4Exs$RP6P{bRm)gLVQnmm!ebD zajnUJAvVGCet7aO{c4IQp7F{sOF&B5*%sLNp3l5zfn5dc&ZmY8mxt{KDTxU(aEd;dY-nDg)o=>LVpchLcS5&wWH-dOn2Xr^H!``Dd(k5)YRi6H zG=j<`SFjDSz0djF(USOxG^3etDYpTW*yHJ}HMxgtvsIR8+hi}E66e$7EY9NjL6klv zZq-xsQ?Q9!3{a*s=JNBuwsKbhS6TjRC zNK(OZ+>pk@U6^&!ro{Ojz07pPZR@6|ponbulSss6>xKvz*O28&jc(m{!JK2Pt+PwH zqMm}BoLrf%4tU?Ul-V%{WlhZi+H;ARU4Tc_TWyJ2)vY@QdvHW#1A&8nQvSVJ*4G3I z3<#21SbuJ5cNQAm`Ta;t*zKwk@E#!;#Ghn`k5O4;B z2h^;4CMF)^#0kyYO!c9y0FEF{2&7Ok2aiqGo%Zalkub(EqO`3;MrgSkp!1YI{?_%P zR{>V;p)aeeSC0R`-H1ka!UHL()9B&LZgIRjvPFHrynCecm6WYxbQBx$>DV>(Hp*)8 zDrTsDvnLeAGT{%($wi9mlFSC5+*VF0^F9XZal7gLfZ=g*5pXi%E%=1LNa-QGdI)1A zfgJ`2TPMEJfHecKLH~&K6iq*AAO2X!R@Q%7ZNLj8&uXV+rJzH8uu}p!z zfK40*TnqnfNG*uGIo)AYv8G-km`(OEQg~HjP}0AA^yWtuu8)YMr%v_nh)mm(hzJB= z7_2Z5k<4eSVj4jFr^Qs7zLHUgS_14WH1p~iXr;VO5P>$p^}07*)F(R2<8RK%V|cSb zUT`+MVy9-nb#{TWZry7{zhdM1OZScJg(#PA`ZHLj35cMUkORaAfaE(xX+MWs@UpP~ zqDPbnJwdO>aJl_fN?pGLV{;et53Ze8m1QO%GL@u!{1xh$jcceOh|hgNbWL&1$N-=g zoV6X;dg=q#ZgcIe=La!IdfATiK)sN+*<}dVWaME~Mu5~8> zl}0fu2Xj@FS65erhHL0fbiJbZ+BZM+o1Z>2tCeb`9x1|Bh#@q!JuY)@-M1I`QAJHB z{0Fz=wZK5~=7^-7i5rHpJ6|=4lGWf~Y&)IR{GqCP!+=Z~(7pY{&DLK91&lV(8I1@0= zR+m@*uT*mI%(FiM9=gt0+^WEUJWDv?d&F_JM6ril= z0k({=c6xReg@=b%0suo|`aC27VlsZ^MD=p4>&?{6mf9dt$zIQH3S)HL@a7<(8HQN{8=Li&?{__@fO;uQyO( zseCM8P<(a7m;oe9!na2mzDBVH-eF$DUu86XgaKJ0q|qNw^frI{pu zxTyy^_c4oKNV`wI{jsCQT%k5_K~Jnu8CZ@FGRGh@l1o9^?c$e~U6}xoCMJIq03%2M zD*Why#0XaA27p&J*!q4z^%wFpw&VT%;$a|SK>1q{2jDLN?Bn1ERK6*NK>q+e-rnBd zVZheEHEu8@2s`UDfL!s8slB*>71|X{*8RbWW@`Di0COkv>-fpe%sj9RAWn>qbtiCdC~xK@x4aL6#tg1l3BbSUSSmOo0(g;lF)11E-wh3r-%#t%hlM9>I=e0X4>(2_Jq;Zo6##WqHN&$|xS^f1~ zSw|-g{I|fau$R6`SSMl~NU0m79$18gnpla@r;&hSH_&3?Wdz+w+>A~@I?Jbo|DdHk z4s6FV$;jC)?5+v`{yESV#{-tl<>*96r~E0onfN}B>rE0P1>0$66E1`1r)M-8&qQ;( zc8y)8KYRX2K25IwDmzKEJ44z%j~tb+6jF!DN{2;)+rv#T?-rdHI1^?aTb^S8pDvpJ zQNZcH%I7*MQK>F>r}BqmWukLhSX-Zgz|o;_E8{Zka&8?#e3*YL<~l>Jfx0;)48(U) zFS2hrq?tUk!QT);5_ahMCD^tzs^SJhBKNtpwr&`v5v<=AI+ z*%0*zGeD9$=ARdTv$~!2aJaC-C$y3r>+Cnc-8=kFhv#!C=pImVB4W413Znoxj$?sy z5bh6-&b%}d_N24|&X0SLX&r>(Wdg^(;|T``WIsW#loxR+I$Z@ zHjsQs?d57s2>vnyr|$@QzCZSo9!LESfMeiP&AQ1<@N!=Uh^Ch-c;b^`3zA}Gu-`69 z*nWssDgPmt&S@Yi&q2gOAkJY5D>29dE9vOyJZ>iFQUIs)h?9eZ1zGy%u)h?^yB|Z0 z-d~;CH=lt33Sh{m6ot>RzyBby%Q=8B)2$RC?RAYOHyNf-w9Ybxw)&tKz}=O-ix~$u zb;5D;aG#icw6I6GG;%SkzL1|J`ZTs<*RG_FB&a2noN{QxU)asd;5e(N>|M*>X+Zu? zc+As6rKkoj#gfnPH*YcC3+tuo`MdFMg^miz(B`#{y0K*8O3>{E{($Ko0Q zOaZ~FEGXiT39HacPyD%Cs;HG%hm6%P`jx2YJlzuF5EZG#oPB3A$ANQY1oqZFZG`9JOo&0C8PgP=8=(+;2~B(u1eYd1hNsuLoI!6yVj+d%mveP_Mr!v z{F(xUoVZPe3_y(_2k4n!#}W)M2TCdlfm&6dNHMYTt_geXLy5lt5qcv4vGzy11L#_R z_zf&I1CSXe;LN>;Ibs0TrvjYROKgFxnc7+%;0eaS_>rlYrUWu*j>ni0V8>A~-K-cm zIu>Kay0Ws;3poBolYn~DxLwRp6KY$O2O32_hl#Suf=R}<&kvu#gJBMlH);+L={2pS z9d3}=)FXCFr$=*bjaV;3)SQ*W@}EbRsO@{V0X`tgAKSoHd5l*)xE$nxdwSeg1wbM6 z0P}B+Ow~iL2$ZqHN**E~T|QDO|3?20^YGF0;bI00VOAJZ^`T8kY#ZQ<$%EWXKLVx! z&ESN5`TC#lFyWc2`pgnf8L8avn_{LUS9e-a`W#Ic;6x?mC1)JK(Gu4#=^q&^RK zMKzQF(mAkk`qf%V@}5(_g3oQmE)lK@fh`INC~(=JX+hD(OzO4OR)A=+4UL2{;qD|4wX{X*MoIbhCWgOofovJFleyN9_XX&-tqDcJbL9xYd?H zIK&ItstSR3T3~wzdgN0z5gE4!2Z-F0gjNN)QaiBzu=DrNedgu=9`?>S!YU*GerbWp zYlfo0DuCCGX)am(-hb|nt}W`F>bCiHzVz$K(mSg}%QyyUP8hZBBV5eJ9#ZaC#r;;# zkS^y0(pBAY^|$H;M~-k>(nUDpwDPL)b#4Td6m|e<3-A*gFbwQhfI3ZHqo+hD)sbi9*X=Hia(Lxsg z$U%Qh?DF%@J$$`q6u=iFfz-ZT>HZ(hTz6Dc%hpG^*8(bDEHtsvLC{czP`pa73Q{AW zL|TAQLWh9pMMT;KqzMTkp-Ynl454|IAR<9p5R%X_LP!vSP(t7xyzl$|dF!q9-uKrx zYh|5G&Yn4YetTx`Jv)0&9x@MtAT(0xN>3R4>)sxiJIysa8VBfpx*NnrD}wV;bMKUu!L{MrH$UA;O#p{4?kwMl465^21bi_k1HYO7tizsC4aIuXA zf%fg?^s1nncBgHY4)FAtKp^?8TUBk%!|hYuaPIa<`zw>t+LnMjvD_I~n6)|!?i&3q zMrZd&`mcUwcV60^7R`At3G)U`gBh+4yIlJi6ER z3+&x_An<3$KS^5R_oUtNbl}UEjeZu5aIPi{`~U{?_1%8*a~^a&{XqaubM&mid2jNY z7aiPd-f__Qr}TKf?-LB)`++C=!QYdH=iK?Yf0Bgr>pXalk8FWlb`IEujU-9*dENMx zA~UXA^r(#Z)R$B5LJ4<@#948`m7gc0mD+1+(D(e5%2Io3tE!AnEy-jP-Dc_=OM`dj zU0OpFCtlBy?S=+_q|V?y+TS&h&uSOttgFg#Xvp7}5v^l27h3C}`e}uXVRrTw?iA1V z!(Yx`J9@SIL;Km!9Umg;4QXp*%W1f&4_hxGB;j)d6*dFo2&9ToNMe)Kw@H8Xg`s@Z z(_sv4#hJ^jBiHy0mrTUG;)=UBw(>31*DBbbny&x)9Lw$1^~+I}!8=|!e02HF(U>Pt zd-m6bk`QnR3=>w`cf!B$vrkTxPw2a>tGodk01`KOGoQa9SGLNu2xT#FyT-p7BulO4 zk-hA7PUJ3MSabCnsX>6&mV}3gB^WtOW1*)N*R}VD&%wWk!&KL`+#mKf=2Nzph7nXi1)lH`&!EfN!WgnI5pgE zEc6<$ick&7D{Wq`aLO)-oSo9gNzzJm{ZvQSX07C za}DlONJyHw5qYo65ouTFd=P`)WTH_Q8MKi#1GY-kC7EX0kL-2q*p}?6H2ffv26g!M z<@5r7MX(;~W=mfR*N&;^gK516<|8_Ygv_OIr|aka%-RqduHZ1Z7 zb{X4fu8{|u0uCVIHIOMGdiAx7SnBHh&|5oink6bo7va1hG7PoUKcdw4D5`D#`zZozuuPeBBG3QH6~2e7C9n2r@g+iVZ7 zV;&*KvS{trOj3KT<{FApv0T6{P)wUe)>tp+wr=Q!!z|Rt4YyPSluE^NJahVV8auaM z7Q`%MTHa?w1X6Ox7uJZjfq3K{Eh68LttvYSWz*S5i)L;crXz&1zMGr@H0T|OrXd6&x7X_ zQDdw;KM?)PX-3lPt%@jVl6rJh8QH~5*70l1EIY75Si!|U?u&i;mrE;Dsnb4C;DFEX zYn4Jg(SOLT^1!@W*=eiZ?J82Q8UEmqg(xZS)M( z#=1gC3KzUEXMbX0VV*1%G4bamXRbl0(+@K-dTJ%3RnBi>5Tiei{Qhy>ZrM)9#g0H< zigjCjjH!=cI&#$dSXiZEbKzGw1c0AxE6L^;IhSvJy@W&) zTzkov9dV|Kh_#bw1}XWK2b@GN;X66qU^>Go7EtW?c%s}&jR|DD8MNxWQRq+5>T4e z6{uWPd51hFS6^mR-@=)69ucVsE^7eyMP!e#Hr=XyFd^~dHQHI8{3o-;(z2w^7;vV4 z2(oQDLD>@ii*!h!x;j)oge90{=9xzf?0FX%O>=Y(gooNa+~ap1EM!`H8^Uk$(Z<&Q z*Sd#$TA^+ELhEM*@zpzjNR5l-iHpO$2R%?^vo4AU+Qz&Ed4ZF8!@#hYU#d4}>+$MZ zs;_fm)8+fFpNB5sB_8?rZvR4kMp{2=7F62o8sl6$pXWO;eJ9w`cwp|9mB?9fzcDJp zX&1-|=73*wKJT(K$0m1b0@KPC&y4=Y#TOUHQ&66+sAj8H?)Sw@aWl1MM&aYF80+P7 z---5NFsAkmBUxa6`wMlxOXcaBfjCFbHTl$SS+;mQw4s@HCLaHeEi0@p}Mi7zef`bh+aNfVwDgPXNwqG}fq-W_vxb7PpAGNSxYye?}=>tcSj>Nfj@jFV*fH-1{KB-}z6E2FH%MRro zZpivSxVH_HPf^re7YTe_9ypS-%N0A2UT5H*evfdV7qVr0xS+UTGhT#1>uUJ7s-9G+@9ypxQi#O=DX-=BN*S? z@_l`j%`ah1=Ntp5f;m0C9}|1yiBh0MC#O&A?s9#)%g+{&M^&`6OyT>6g#G`;vZLb; zK9I`cipbvGyr901$AKjLKbHMJF#i9Zzws}qbCaFr^YsQ*|Z-FU=}k)nUmNFx11z|}MGOSkO%XQr{ch3J{9wVxa=kzKta zDwsWT?FH&a7t@RD9bUB$1v>JTY*C|HD#Z)4-czn$>Wny*)VU=zn3HadQ4mdWN$Z-a zhvDRIRzKW>=hIW5>ZKa#Z0#wZ<%BYqwouMfwPyd-M(TxNtrPLjET)q|6G!5&gZ;-_ zBES<`8o*VYFFsTh+U6)b%AfEqCGOfJ9*Bo2<(WUfEst}`u&Z`jLxiCK?h3o_KewqE zTA zP1V0BQ;n0M>8qeD^}MRNjZwufDk|px#Ic2z!?nK-xdw2Qb2y~yTiWTyi%$Vu0q#Zt zuz|y^W{L|+T|wa5Y|)>)jhpTk78YqvJ`|O_PpNK<_;*u41nlblC> z`V#=UU@dNx$*$bIriqVaw-Z4DWhnr}c8h@I6`geBPm;Vy%xXgUi2?$zqv-lDYr4C;;{YiAtC<-X zAOfy%I_YRQWr~##D%HvCKC>KiHc>xS6q-86s>Ov~IezGj03Z=}=@bD6pROe!LJ1Z= z0#_rd);Qr{e>uN_4Ob=xYteE|OU~w~-t^^I&*k)Iw@{(J)jF!0nwsa`jS^EpGBhq6 z28&cZerVfp0OrjCWxqa*Yd}$&P^6=eivekyCF;A`Te^~-O+7=Bm@7dP=Bh#1jT`TH zGlHNccg0$n&w{@QuVgo|t|MK`x2d7FGcEG#!Y6HHcM$9EgjMcVR~u%jr{kQF(!8T?4vzsljn~ec;o}L=)SKE9++Q!goX}JFG6mik>Wv_T+<9@ zG{yck)je4=n{xy&^Sh$i`Qu(zCDy&@9UYOhE@+;)$N9`|)r5CbhU*?rKpwcL=)L(3 z2)OXwQ~*>yON+sFm(Gm%B#a0G^`Qw!k7RE-yBO(A5!sWE$YZ-J*^cE)3f{382%ip2~TZeb@fh(+eFUYH)8auML6qhMTfOGA5+*dSJ3eeGu0)FB=59&=Z3? z73`i38?h*{PJ{S#4bHE=@T9aw7pJn+;YiDjNaZjcA7&Nn+x+V4sz3^8T`Mudq%d|T z;tr|&wQAVvkl*0Y&`?76{UGCvg4w8++xR_QfwG*aBePHCt0U5`1&wB7Eiau&9RJ%5U~26#^{0kinN=7UA~3^B{Mi% zG(M)om8gh5ofKkj zRI5pJJ+sHr#g9cnAQzAIQ@pH%lC+m%065ylGcGqX8i6|+6wW@be{wEgq^Nk}xWxGALGlUCNoo zhDVSZda^9n6`$8#l}O*6k@iE+GB5-^l7D=dsY*8rT&bM^{*~esB|D)q&kFPcW++;9 zWq)fXOYFOupDS$hI$olkbqLomk-%5IgpK_guGPKFn=w5&I9PbK3)}BR$?Cp;0ORYb zrLixP%6!@Xtvgdg^0Z@t=EC2Ayvvhi5EDH;0L z_pud-N~g7qpMe{-D|-W233}tPWJUtkUI$=2I^Mt6zX&Mn>Ess_FICuFM9&)tkRUF6 zEdKfkN(d7|Z?mA7%)%|Ktaj_DjTYwSl0d^_0A#A7ICK*&r`N&(PzNd0`=-xL8Xwd8 z2l4^yhb}1a75HWU2oQl+^o+GEwXV1)$H_#XZ_P!E0vX>2@t0E&CtmjH?QT1+I{=A{ z5I|!_l4Rli%pM09kj5029IC}^K6~hw$Fw8KtZB^D@aX!7hX zwJq7OnCt|;!|FY=l(Ye4g({ld=)V7Yl-728lhrUjp3k?LdZVbV7Rw#hs>S4Cww&to z#mQqe1>wTS01JR$c1=O-z2^OaRp-pIgQ{q&i+o%%VDM-dH_)1G)tTBLK}l~9*ILD| zz4O;fE~XpXx8+;)h)C>3&>mPt#5PuCR7_a@6-~Av_i#tCrhqj>dQ~GevP@Bm!O)JC z708m(a0C6pGvvHWk>gKq>t>_1#CO02naCT63cfH$=$nl!J#e}F4AA5MwM=^M3P@Z- VH}q-fB<=NKVqmFXbN%kae*lxTplbjC literal 0 HcmV?d00001 diff --git a/interfaces/innerkits/native_cpp/screen_sink/BUILD.gn b/interfaces/innerkits/native_cpp/screen_sink/BUILD.gn new file mode 100644 index 00000000..bcbb3e9b --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/BUILD.gn @@ -0,0 +1,55 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_sink_sdk") { + include_dirs = [ + "//utils/system/safwk/native/include", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "include", + "${common_path}/include", + ] + + sources = [ + "src/dscreen_sink_handler.cpp", + "src/dscreen_sink_proxy.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${common_path}:distributed_screen_utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensinksdk\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_handler.h b/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_handler.h new file mode 100644 index 00000000..152884de --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_handler.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SINK_HANDLER_H +#define OHOS_DSCREEN_SINK_HANDLER_H + +#include + +#include "idistributed_hardware_sink.h" +#include "single_instance.h" + +#include "idscreen_sink.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSinkHandler : public IDistributedHardwareSink { +DECLARE_SINGLE_INSTANCE_BASE(DScreenSinkHandler); +public: + int32_t InitSink(const std::string ¶ms) override; + int32_t ReleaseSink() override; + int32_t SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) override; + int32_t UnsubscribeLocalHardware(const std::string &dhId) override; + void OnRemoteSinkSvrDied(const wptr &remote); +private: + class DScreenSinkSvrRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr &remote) override; + }; + + DScreenSinkHandler(); + ~DScreenSinkHandler(); + + std::mutex mutex_; + sptr dScreenSinkProxy_ = nullptr; + sptr sinkSvrRecipient_ = nullptr; +}; + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((visibility("default"))) IDistributedHardwareSink *GetSinkHardwareHandler(); +#ifdef __cplusplus +} +#endif +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_proxy.h b/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_proxy.h new file mode 100644 index 00000000..ca69db10 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/include/dscreen_sink_proxy.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SINK_PROXY_H +#define OHOS_DSCREEN_SINK_PROXY_H + +#include "iremote_broker.h" +#include "iremote_proxy.h" + +#include "idscreen_sink.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSinkProxy : public IRemoteProxy { +public: + explicit DScreenSinkProxy(const sptr impl) + : IRemoteProxy(impl) + { + } + + ~DScreenSinkProxy() {} + int32_t InitSink(const std::string ¶ms) override; + int32_t ReleaseSink() override; + int32_t SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) override; + int32_t UnsubscribeLocalHardware(const std::string &dhId) override; + void DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif diff --git a/interfaces/innerkits/native_cpp/screen_sink/include/idscreen_sink.h b/interfaces/innerkits/native_cpp/screen_sink/include/idscreen_sink.h new file mode 100644 index 00000000..96be07e5 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/include/idscreen_sink.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IDSCREEN_SINK_H +#define OHOS_IDSCREEN_SINK_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace DistributedHardware { +class IDScreenSink : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.distributedscreensink"); + enum { + INIT_SINK = 0, + RELEASE_SINK = 1, + SUBSCRIBE_DISTRIBUTED_HARDWARE = 2, + UNSUBSCRIBE_DISTRIBUTED_HARDWARE = 3, + DSCREEN_NOTIFY = 4, + }; + + IDScreenSink() = default; + virtual ~IDScreenSink() = default; + virtual int32_t InitSink(const std::string ¶ms) = 0; + virtual int32_t ReleaseSink() = 0; + virtual int32_t SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) = 0; + virtual int32_t UnsubscribeLocalHardware(const std::string &dhId) = 0; + virtual void DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_handler.cpp b/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_handler.cpp new file mode 100644 index 00000000..8f4472cc --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_handler.cpp @@ -0,0 +1,136 @@ +/* + * 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 "dscreen_sink_handler.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DScreenSinkHandler); + +DScreenSinkHandler::DScreenSinkHandler() +{ + DHLOGI("DScreenSinkHandler construct."); + std::lock_guard lock(mutex_); + if (!sinkSvrRecipient_) { + sinkSvrRecipient_ = new DScreenSinkSvrRecipient(); + } +} + +DScreenSinkHandler::~DScreenSinkHandler() +{ + DHLOGI("~DScreenSinkHandler."); +} + +int32_t DScreenSinkHandler::InitSink(const std::string ¶ms) +{ + DHLOGD("InitSink"); + std::lock_guard lock(mutex_); + + if (!dScreenSinkProxy_) { + sptr samgr = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!samgr) { + DHLOGE("Failed to get system ability mgr."); + return ERR_DH_SCREEN_SA_GET_SAMGR_FAIL; + } + sptr remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID); + if (!remoteObject) { + DHLOGE("Failed to get dscreen sink service."); + return ERR_DH_SCREEN_SA_GET_SINKSERVICE_FAIL; + } + + remoteObject->AddDeathRecipient(sinkSvrRecipient_); + dScreenSinkProxy_ = iface_cast(remoteObject); + if ((!dScreenSinkProxy_) || (!dScreenSinkProxy_->AsObject())) { + DHLOGE("Failed to get dscreen sink proxy."); + return ERR_DH_SCREEN_SA_GET_SINKPROXY_FAIL; + } + } + int32_t ret = dScreenSinkProxy_->InitSink(params); + return ret; +} + +int32_t DScreenSinkHandler::ReleaseSink() +{ + DHLOGD("ReleaseSink"); + std::lock_guard lock(mutex_); + if (!dScreenSinkProxy_) { + DHLOGE("screen sink proxy not init."); + return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT; + } + + int32_t ret = dScreenSinkProxy_->ReleaseSink(); + return ret; +} + +int32_t DScreenSinkHandler::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) +{ + DHLOGD("SubscribeLocalHardware"); + std::lock_guard lock(mutex_); + if (!dScreenSinkProxy_) { + DHLOGE("screen sink proxy not init."); + return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT; + } + int32_t ret = dScreenSinkProxy_->SubscribeLocalHardware(dhId, param); + return ret; +} + +int32_t DScreenSinkHandler::UnsubscribeLocalHardware(const std::string &dhId) +{ + DHLOGD("UnsubscribeLocalHardware"); + std::lock_guard lock(mutex_); + if (!dScreenSinkProxy_) { + DHLOGE("screen sink proxy not init."); + return ERR_DH_SCREEN_SA_SINKPROXY_NOT_INIT; + } + int32_t ret = dScreenSinkProxy_->UnsubscribeLocalHardware(dhId); + return ret; +} + +void DScreenSinkHandler::DScreenSinkSvrRecipient::OnRemoteDied(const wptr &remote) +{ + DHLOGI("DScreenSinkSvrRecipient OnRemoteDied."); + DScreenSinkHandler::GetInstance().OnRemoteSinkSvrDied(remote); +} + +void DScreenSinkHandler::OnRemoteSinkSvrDied(const wptr &remote) +{ + DHLOGI("OnRemoteSinkSvrDied"); + sptr remoteObject = remote.promote(); + if (!remoteObject) { + DHLOGE("OnRemoteDied remote promoted failed"); + return; + } + std::lock_guard lock(mutex_); + if (!dScreenSinkProxy_) { + dScreenSinkProxy_->AsObject()->RemoveDeathRecipient(sinkSvrRecipient_); + dScreenSinkProxy_ = nullptr; + } +} + +IDistributedHardwareSink *GetSinkHardwareHandler() +{ + DHLOGD("GetSinkHardwareHandler"); + return &DScreenSinkHandler::GetInstance(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp b/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp new file mode 100644 index 00000000..a6d1e999 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp @@ -0,0 +1,123 @@ +/* + * 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 "dscreen_sink_proxy.h" + +#include "parcel.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DScreenSinkProxy::InitSink(const std::string ¶ms) +{ + DHLOGD("InitSink"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(params)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(INIT_SINK, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSinkProxy::ReleaseSink() +{ + DHLOGD("ReleaseSink"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + Remote()->SendRequest(RELEASE_SINK, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSinkProxy::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) +{ + DHLOGD("SubscribeLocalHardware"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(dhId) || !data.WriteString(param)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(SUBSCRIBE_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSinkProxy::UnsubscribeLocalHardware(const std::string &dhId) +{ + DHLOGD("UnsubscribeLocalHardware"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(dhId)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(UNSUBSCRIBE_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +void DScreenSinkProxy::DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) +{ + DHLOGD("DScreenNotify"); + MessageParcel data; + MessageParcel reply; + MessageOption option = { MessageOption::TF_ASYNC }; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return; + } + + if (!data.WriteString(devId) || !data.WriteInt32(eventCode) || !data.WriteString(eventContent)) { + DHLOGE("Write param failed."); + return; + } + + Remote()->SendRequest(DSCREEN_NOTIFY, data, reply, option); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/BUILD.gn b/interfaces/innerkits/native_cpp/screen_source/BUILD.gn new file mode 100644 index 00000000..fec91820 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/BUILD.gn @@ -0,0 +1,58 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_source_sdk") { + include_dirs = [ + "//utils/system/safwk/native/include", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "include", + "include/callback", + "${common_path}/include", + ] + + sources = [ + "src/dscreen_source_handler.cpp", + "src/dscreen_source_proxy.cpp", + "src/callback/dscreen_source_callback_stub.cpp", + "src/callback/dscreen_source_callback.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${common_path}:distributed_screen_utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensourcesdk\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback.h b/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback.h new file mode 100644 index 00000000..3eb89dda --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_CALLBACK_H +#define OHOS_DSCREEN_SOURCE_CALLBACK_H + +#include + +#include "idistributed_hardware_source.h" + +#include "dscreen_source_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceCallback : public DScreenSourceCallbackStub { +public: + DScreenSourceCallback() = default; + ~DScreenSourceCallback(); + + int32_t OnNotifyRegResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) override; + int32_t OnNotifyUnregResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) override; + + void PushRegRegisterCallback(const std::string &reqId, const std::shared_ptr &callback); + void PopRegRegisterCallback(const std::string &reqId); + void PushUnregisterCallback(const std::string &reqId, const std::shared_ptr &callback); + void PopUnregisterCallback(const std::string &reqId); + +private: + std::map> registerCallbackMap_; + std::map> unregisterCallbackMap_; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback_stub.h b/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback_stub.h new file mode 100644 index 00000000..f85c25e0 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/callback/dscreen_source_callback_stub.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_CALLBACK_STUB_H +#define OHOS_DSCREEN_SOURCE_CALLBACK_STUB_H + +#include + +#include "iremote_stub.h" + +#include "idscreen_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceCallbackStub : public IRemoteStub { +public: + DScreenSourceCallbackStub(); + virtual ~DScreenSourceCallbackStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +private: + using DScreenFunc = int32_t (DScreenSourceCallbackStub::*)(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + std::map memberFuncMap_; + + int32_t OnNotifyRegResultInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t OnNotifyUnregResultInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/include/callback/idscreen_source_callback.h b/interfaces/innerkits/native_cpp/screen_source/include/callback/idscreen_source_callback.h new file mode 100644 index 00000000..5f880c37 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/callback/idscreen_source_callback.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IDSCREEN_SOURCE_CALLBACK_H +#define OHOS_IDSCREEN_SOURCE_CALLBACK_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace DistributedHardware { +class IDScreenSourceCallback : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.dscreensourcecallback"); + enum { + NOTIFY_REG_RESULT = 0, + NOTIFY_UNREG_RESULT, + }; + + virtual ~IDScreenSourceCallback() {} + virtual int32_t OnNotifyRegResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) = 0; + virtual int32_t OnNotifyUnregResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_handler.h b/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_handler.h new file mode 100644 index 00000000..0ee40a01 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_handler.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_HANDLER_H +#define OHOS_DSCREEN_SOURCE_HANDLER_H + +#include + +#include "dscreen_source_callback.h" +#include "idscreen_source.h" +#include "idistributed_hardware_source.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceHandler : public IDistributedHardwareSource { +DECLARE_SINGLE_INSTANCE_BASE(DScreenSourceHandler); +public: + int32_t InitSource(const std::string ¶ms) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string &devId, const std::string &dhId, + const EnableParam ¶m, std::shared_ptr callback) override; + int32_t UnregisterDistributedHardware(const std::string &devId, const std::string &dhId, + std::shared_ptr callback) override; + int32_t ConfigDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &key, const std::string &value) override; + void OnRemoteSourceSvrDied(const wptr &remote); +private: + class DScreenSourceSvrRecipient : public IRemoteObject::DeathRecipient { + public: + void OnRemoteDied(const wptr &remote) override; + }; + + DScreenSourceHandler(); + ~DScreenSourceHandler(); + + std::mutex mutex_; + sptr dScreenSourceProxy_ = nullptr; + sptr dScreenSourceCallback_ = nullptr; + sptr sourceSvrRecipient_ = nullptr; +}; + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((visibility("default"))) IDistributedHardwareSource *GetSourceHardwareHandler(); +#ifdef __cplusplus +} +#endif +} +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_proxy.h b/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_proxy.h new file mode 100644 index 00000000..a0d84ba0 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/dscreen_source_proxy.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 OHOS_DSCREEN_SOURCE_PROXY_H +#define OHOS_DSCREEN_SOURCE_PROXY_H + +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "idscreen_source.h" +#include "idistributed_hardware_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceProxy : public IRemoteProxy { +public: + explicit DScreenSourceProxy(const sptr impl) + : IRemoteProxy(impl) + { + } + + ~DScreenSourceProxy() {} + int32_t InitSource(const std::string ¶ms, const sptr &callback) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string &devId, const std::string &dhId, + const EnableParam ¶m, const std::string &reqId) override; + int32_t UnregisterDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &reqId) override; + int32_t ConfigDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &key, const std::string &value) override; + void DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) override; + +private: + static inline BrokerDelegator delegator_; +}; +} +} +#endif diff --git a/interfaces/innerkits/native_cpp/screen_source/include/idscreen_source.h b/interfaces/innerkits/native_cpp/screen_source/include/idscreen_source.h new file mode 100644 index 00000000..6c1a69ed --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/include/idscreen_source.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IDSCREEN_SOURCE_H +#define OHOS_IDSCREEN_SOURCE_H + +#include "iremote_broker.h" +#include "idscreen_source_callback.h" +#include "idistributed_hardware_source.h" + +namespace OHOS { +namespace DistributedHardware { +class IDScreenSource : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedhardware.distributedscreensource"); + enum { + INIT_SOURCE = 0, + RELEASE_SOURCE, + REGISTER_DISTRIBUTED_HARDWARE, + UNREGISTER_DISTRIBUTED_HARDWARE, + CONFIG_DISTRIBUTED_HARDWARE, + DSCREEN_NOTIFY, + }; + + virtual ~IDScreenSource() {} + virtual int32_t InitSource(const std::string ¶ms, const sptr &callback) = 0; + virtual int32_t ReleaseSource() = 0; + virtual int32_t RegisterDistributedHardware(const std::string &devId, const std::string &dhId, + const EnableParam ¶m, const std::string &reqId) = 0; + virtual int32_t UnregisterDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &reqId) = 0; + virtual int32_t ConfigDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &key, const std::string &value) = 0; + virtual void DScreenNotify(const std::string &devId, int32_t eventCode, + const std::string &eventContent) = 0; +}; +} +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback.cpp b/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback.cpp new file mode 100644 index 00000000..038f6c19 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback.cpp @@ -0,0 +1,79 @@ +/* + * 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 "dscreen_source_callback.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +DScreenSourceCallback::~DScreenSourceCallback() {} + +int32_t DScreenSourceCallback::OnNotifyRegResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGD("OnNotifyRegResult"); + auto iter = registerCallbackMap_.find(reqId); + if (iter != registerCallbackMap_.end()) { + iter->second->OnRegisterResult(devId, dhId, status, data); + registerCallbackMap_.erase(reqId); + return DH_SUCCESS; + } + + return ERR_DH_SCREEN_SA_REGISTERCALLBACK_NOT_FOUND; +} + +int32_t DScreenSourceCallback::OnNotifyUnregResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGD("OnNotifyUnregResult"); + auto iter = unregisterCallbackMap_.find(reqId); + if (iter != unregisterCallbackMap_.end()) { + iter->second->OnUnregisterResult(devId, dhId, status, data); + unregisterCallbackMap_.erase(reqId); + return DH_SUCCESS; + } + + return ERR_DH_SCREEN_SA_UNREGISTERCALLBACK_NOT_FOUND; +} + +void DScreenSourceCallback::PushRegRegisterCallback(const std::string &reqId, + const std::shared_ptr &callback) +{ + DHLOGD("PushRegRegisterCallback"); + registerCallbackMap_.emplace(reqId, callback); +} + +void DScreenSourceCallback::PopRegRegisterCallback(const std::string &reqId) +{ + DHLOGD("PopRegRegisterCallback"); + registerCallbackMap_.erase(reqId); +} + +void DScreenSourceCallback::PushUnregisterCallback(const std::string &reqId, + const std::shared_ptr &callback) +{ + DHLOGD("PushUnregisterCallback"); + unregisterCallbackMap_.emplace(reqId, callback); +} + +void DScreenSourceCallback::PopUnregisterCallback(const std::string &reqId) +{ + DHLOGD("PopUnregisterCallback"); + unregisterCallbackMap_.erase(reqId); +} +} +} \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback_stub.cpp b/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback_stub.cpp new file mode 100644 index 00000000..08f9ce8c --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/src/callback/dscreen_source_callback_stub.cpp @@ -0,0 +1,69 @@ +/* + * 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 "dscreen_source_callback_stub.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +DScreenSourceCallbackStub::DScreenSourceCallbackStub() +{ + memberFuncMap_[NOTIFY_REG_RESULT] = &DScreenSourceCallbackStub::OnNotifyRegResultInner; + memberFuncMap_[NOTIFY_UNREG_RESULT] = &DScreenSourceCallbackStub::OnNotifyUnregResultInner; +} + +DScreenSourceCallbackStub::~DScreenSourceCallbackStub() +{ +} + +int32_t DScreenSourceCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + std::map::iterator iter = memberFuncMap_.find(code); + if (iter == memberFuncMap_.end()) { + DHLOGE("invalid request code."); + return ERR_DH_SCREEN_SA_REQUEST_CODE_INVALID; + } + DScreenFunc &func = iter->second; + return (this->*func)(data, reply, option); +} + +int32_t DScreenSourceCallbackStub::OnNotifyRegResultInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + int32_t status = data.ReadInt32(); + std::string resultData = data.ReadString(); + int32_t ret = OnNotifyRegResult(devId, dhId, reqId, status, resultData); + return ret; +} + +int32_t DScreenSourceCallbackStub::OnNotifyUnregResultInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + int32_t status = data.ReadInt32(); + std::string resultData = data.ReadString(); + int32_t ret = OnNotifyRegResult(devId, dhId, reqId, status, resultData); + return ret; +} +} +} \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_handler.cpp b/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_handler.cpp new file mode 100644 index 00000000..ed5e3c0f --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_handler.cpp @@ -0,0 +1,166 @@ +/* + * 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 "dscreen_source_handler.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DScreenSourceHandler); + +DScreenSourceHandler::DScreenSourceHandler() +{ + DHLOGI("DScreenSourceHandler construct."); + std::lock_guard lock(mutex_); + if (!sourceSvrRecipient_) { + sourceSvrRecipient_ = new DScreenSourceSvrRecipient(); + } + + if (!dScreenSourceCallback_) { + dScreenSourceCallback_ = new DScreenSourceCallback(); + } +} + +DScreenSourceHandler::~DScreenSourceHandler() +{ + DHLOGI("~DScreenSourceHandler."); +} + +int32_t DScreenSourceHandler::InitSource(const std::string ¶ms) +{ + DHLOGD("InitSource"); + std::lock_guard lock(mutex_); + + if (!dScreenSourceProxy_) { + sptr samgr = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!samgr) { + DHLOGE("Failed to get system ability mgr."); + return ERR_DH_SCREEN_SA_GET_SAMGR_FAIL; + } + sptr remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID); + if (!remoteObject) { + DHLOGE("Failed to get dscreen source service."); + return ERR_DH_SCREEN_SA_GET_SOURCESERVICE_FAIL; + } + + remoteObject->AddDeathRecipient(sourceSvrRecipient_); + dScreenSourceProxy_ = iface_cast(remoteObject); + if ((!dScreenSourceProxy_) || (!dScreenSourceProxy_->AsObject())) { + DHLOGE("Failed to get dscreen source proxy."); + return ERR_DH_SCREEN_SA_GET_SOURCEPROXY_FAIL; + } + } + + int32_t ret = dScreenSourceProxy_->InitSource(params, dScreenSourceCallback_); + return ret; +} + +int32_t DScreenSourceHandler::ReleaseSource() +{ + DHLOGD("ReleaseSource"); + std::lock_guard lock(mutex_); + if (!dScreenSourceProxy_) { + DHLOGE("screen source proxy not init."); + return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT; + } + int32_t ret = dScreenSourceProxy_->ReleaseSource(); + return ret; +} + +int32_t DScreenSourceHandler::RegisterDistributedHardware(const std::string &devId, + const std::string &dhId, const EnableParam ¶m, std::shared_ptr callback) +{ + DHLOGD("RegisterDistributedHardware, devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + std::lock_guard lock(mutex_); + if (!dScreenSourceProxy_) { + DHLOGE("screen source proxy not init."); + return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT; + } + if (!dScreenSourceCallback_) { + DHLOGE("screen source callback is null."); + return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT; + } + + std::string reqId = GetRandomID(); + dScreenSourceCallback_->PushRegRegisterCallback(reqId, callback); + int ret = dScreenSourceProxy_->RegisterDistributedHardware(devId, dhId, param, reqId); + return ret; +} + +int32_t DScreenSourceHandler::UnregisterDistributedHardware(const std::string &devId, + const std::string &dhId, std::shared_ptr callback) +{ + DHLOGD("UnregisterDistributedHardware, devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + std::lock_guard lock(mutex_); + if (!dScreenSourceProxy_) { + DHLOGE("screen source proxy not init."); + return ERR_DH_SCREEN_SA_SOURCEPROXY_NOT_INIT; + } + if (!dScreenSourceCallback_) { + DHLOGE("screen source callback is null."); + return ERR_DH_SCREEN_SA_SOURCEPCALLBACK_NOT_INIT; + } + + std::string reqId = GetRandomID(); + dScreenSourceCallback_->PushUnregisterCallback(reqId, callback); + int ret = dScreenSourceProxy_->UnregisterDistributedHardware(devId, dhId, reqId); + return ret; +} + +int32_t DScreenSourceHandler::ConfigDistributedHardware(const std::string &devId, + const std::string &dhId, const std::string &key, const std::string &value) +{ + DHLOGD("ConfigDistributedHardware"); + return DH_SUCCESS; +} + +void DScreenSourceHandler::DScreenSourceSvrRecipient::OnRemoteDied(const wptr &remote) +{ + DHLOGI("DScreenSourceSvrRecipient OnRemoteDied"); + DScreenSourceHandler::GetInstance().OnRemoteSourceSvrDied(remote); +} + +void DScreenSourceHandler::OnRemoteSourceSvrDied(const wptr &remote) +{ + DHLOGI("OnRemoteSourceSvrDied"); + sptr remoteObject = remote.promote(); + if (!remoteObject) { + DHLOGE("OnRemoteDied remote promoted failed"); + return; + } + std::lock_guard lock(mutex_); + if (!dScreenSourceProxy_) { + dScreenSourceProxy_->AsObject()->RemoveDeathRecipient(sourceSvrRecipient_); + dScreenSourceProxy_ = nullptr; + } +} + +IDistributedHardwareSource *GetSourceHardwareHandler() +{ + DHLOGD("GetSourceHardwareHandler"); + return &DScreenSourceHandler::GetInstance(); +} +} +} \ No newline at end of file diff --git a/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp b/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp new file mode 100644 index 00000000..5f0bad83 --- /dev/null +++ b/interfaces/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp @@ -0,0 +1,145 @@ +/* + * 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 "dscreen_source_proxy.h" + +#include "parcel.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DScreenSourceProxy::InitSource(const std::string ¶ms, const sptr &callback) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(params) + || !data.WriteRemoteObject(callback->AsObject())) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(INIT_SOURCE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSourceProxy::ReleaseSource() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + Remote()->SendRequest(RELEASE_SOURCE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSourceProxy::RegisterDistributedHardware(const std::string &devId, + const std::string &dhId, const EnableParam ¶m, const std::string &reqId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) + || !data.WriteString(param.version) || !data.WriteString(param.attrs) + || !data.WriteString(reqId)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + Remote()->SendRequest(REGISTER_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSourceProxy::UnregisterDistributedHardware(const std::string &devId, + const std::string &dhId, const std::string &reqId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) + || !data.WriteString(reqId)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + Remote()->SendRequest(UNREGISTER_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +int32_t DScreenSourceProxy::ConfigDistributedHardware(const std::string &devId, + const std::string &dhId, const std::string &key, const std::string &value) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) + || !data.WriteString(key) || !data.WriteString(value)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + Remote()->SendRequest(CONFIG_DISTRIBUTED_HARDWARE, data, reply, option); + int32_t ret = reply.ReadInt32(); + return ret; +} + +void DScreenSourceProxy::DScreenNotify(const std::string &devId, + int32_t eventCode, const std::string &eventContent) +{ + DHLOGD("DScreenNotify"); + MessageParcel data; + MessageParcel reply; + MessageOption option = { MessageOption::TF_ASYNC }; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed"); + return; + } + + if (!data.WriteString(devId) || !data.WriteInt32(eventCode) || !data.WriteString(eventContent)) { + DHLOGE("Write param failed."); + return; + } + + Remote()->SendRequest(DSCREEN_NOTIFY, data, reply, option); +} +} +} diff --git a/sa_profile/4807.xml b/sa_profile/4807.xml new file mode 100644 index 00000000..f3f552e2 --- /dev/null +++ b/sa_profile/4807.xml @@ -0,0 +1,27 @@ + + + + dhardware + + 4807 + libdistributed_screen_source.z.so + + + true + true + 1 + + diff --git a/sa_profile/4808.xml b/sa_profile/4808.xml new file mode 100644 index 00000000..6ec95fd4 --- /dev/null +++ b/sa_profile/4808.xml @@ -0,0 +1,27 @@ + + + + dhardware + + 4808 + libdistributed_screen_sink.z.so + + + true + true + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 00000000..6b167fbb --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,23 @@ +# 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. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("dscreen_sa_profile") { + sources = [ + "4807.xml", + "4808.xml", + ] + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/screenhandler/BUILD.gn b/screenhandler/BUILD.gn new file mode 100644 index 00000000..cd5c1ec4 --- /dev/null +++ b/screenhandler/BUILD.gn @@ -0,0 +1,56 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_handler") { + include_dirs = [ + "//third_party/json/include", + "${windowmanager_path}/interfaces/innerkits/dm", + "${mediastandard_path}/interfaces/innerkits/native/media/include", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "include", + "${common_path}/include", + ] + + sources = [ + "src/dscreen_handler.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${mediastandard_path}/interfaces/innerkits/native/media:media_client", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/dm:libdm", + "${common_path}:distributed_screen_utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreenhandler\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/screenhandler/include/dscreen_handler.h b/screenhandler/include/dscreen_handler.h new file mode 100644 index 00000000..5dae8783 --- /dev/null +++ b/screenhandler/include/dscreen_handler.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_HANDLER_H +#define OHOS_DSCREEN_HANDLER_H + +#include "screen_manager.h" + +#include "ihardware_handler.h" +#include "single_instance.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenHandler : public IHardwareHandler, public Rosen::ScreenManager::IScreenListener { +DECLARE_SINGLE_INSTANCE_BASE(DScreenHandler); +public: + void OnConnect(uint64_t screenId) override; + void OnDisconnect(uint64_t screenId) override; + void OnChange(uint64_t screenId) override {}; + int32_t Initialize() override; + std::vector Query() override; + std::map QueryExtraInfo() override; + bool IsSupportPlugin() override; + void RegisterPluginListener(std::shared_ptr listener) override; + +private: + DScreenHandler(); + ~DScreenHandler(); + std::string QueryCodecInfo(); + + std::shared_ptr listener_ = nullptr; + std::string codecInfoStr_; +}; + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((visibility("default"))) IHardwareHandler* GetHardwareHandler(); +#ifdef __cplusplus +} +#endif +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/screenhandler/src/dscreen_handler.cpp b/screenhandler/src/dscreen_handler.cpp new file mode 100644 index 00000000..7da13653 --- /dev/null +++ b/screenhandler/src/dscreen_handler.cpp @@ -0,0 +1,152 @@ +/* + * 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 "dscreen_handler.h" + +#include "avcodec_info.h" +#include "avcodec_list.h" +#include "nlohmann/json.hpp" +#include "screen.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DScreenHandler); + +DScreenHandler::DScreenHandler() +{ + DHLOGI("DScreenHandler constructor."); +} + +DScreenHandler::~DScreenHandler() +{ + DHLOGI("~DScreenHandler"); +} + +int32_t DScreenHandler::Initialize() +{ + DHLOGI("DScreenHandler Initialize"); + bool ret = Rosen::ScreenManager::GetInstance().RegisterScreenListener(this); + if (!ret) { + DHLOGE("register screen listener failed."); + } + return DH_SUCCESS; +} + +void DScreenHandler::OnConnect(uint64_t screenId) +{ + DHLOGI("on screen connect"); + if (screenId != SCREEN_ID_DEFAULT) { + return; + } + std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId); + sptr screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId); + uint32_t screenWidth = screen->GetWidth(); + uint32_t screenHeight = screen->GetHeight(); + + json attrJson; + attrJson[KEY_VERSION] = DSCREEN_VERSION; + attrJson[KEY_SCREEN_WIDTH] = screenWidth; + attrJson[KEY_SCREEN_HEIGHT] = screenHeight; + attrJson[KEY_CODECTYPE] = QueryCodecInfo(); + + if (listener_ != nullptr) { + listener_->PluginHardware(dhId, attrJson.dump()); + } +} + +void DScreenHandler::OnDisconnect(uint64_t screenId) +{ + DHLOGI("on screen disconnect"); + std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId); + if (listener_ != nullptr) { + listener_->UnPluginHardware(dhId); + } +} + +std::vector DScreenHandler::Query() +{ + DHLOGI("DScreenHandler query hardware info"); + std::vector dhItemVec; + std::vector> screens = Rosen::ScreenManager::GetInstance().GetAllScreens(); + sptr screen = screens[SCREEN_ID_DEFAULT]; + std::string dhId = SCREEN_PREFIX + SEPERATOR + std::to_string(screen->GetId()); + uint32_t screenWidth = screen->GetWidth(); + uint32_t screenHeight = screen->GetHeight(); + + json attrJson; + attrJson[KEY_VERSION] = DSCREEN_VERSION; + attrJson[KEY_SCREEN_WIDTH] = screenWidth; + attrJson[KEY_SCREEN_HEIGHT] = screenHeight; + attrJson[KEY_CODECTYPE] = QueryCodecInfo(); + + DHItem dhItem; + dhItem.dhId = dhId; + dhItem.attrs = attrJson.dump(); + dhItemVec.push_back(dhItem); + DHLOGD("query result: dhId: %s, attrs: %s", GetAnonyString(dhId).c_str(), attrJson.dump().c_str()); + + return dhItemVec; +} + +std::map DScreenHandler::QueryExtraInfo() +{ + DHLOGD("DScreenHandler queryExtraInfo"); + std::map extraInfo; + return extraInfo; +} + +bool DScreenHandler::IsSupportPlugin() +{ + DHLOGD("DScreenHandler IsSupportPlugin"); + return true; +} + +void DScreenHandler::RegisterPluginListener(std::shared_ptr listener) +{ + DHLOGD("DScreenHandler register plugin listener"); + listener_ = listener; +} + +std::string DScreenHandler::QueryCodecInfo() +{ + DHLOGD("DScreenHandler QueryCodecInfo"); + if (!codecInfoStr_.empty()) { + return codecInfoStr_; + } + + // query codec info + std::shared_ptr codecList = Media::AVCodecListFactory::CreateAVCodecList(); + std::vector> caps = codecList->GetVideoEncoderCaps(); + for (const auto &cap : caps) { + std::shared_ptr codecInfo = cap->GetCodecInfo(); + codecInfoStr_.append(codecInfo->GetName()); + codecInfoStr_.append(SEPERATOR); + } + return codecInfoStr_; +} + +IHardwareHandler* GetHardwareHandler() +{ + return &DScreenHandler::GetInstance(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/common/databuffer/include/data_buffer.h b/services/common/databuffer/include/data_buffer.h new file mode 100644 index 00000000..0c876f92 --- /dev/null +++ b/services/common/databuffer/include/data_buffer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DATA_BUFFER_H +#define OHOS_DATA_BUFFER_H + +#include + +namespace OHOS { +namespace DistributedHardware { +class DataBuffer { +public: + explicit DataBuffer(size_t capacity); + ~DataBuffer(); + + size_t Capacity() const; + uint8_t *Data() const; + +private: + size_t capacity_ = 0; + uint8_t *data_ = nullptr; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/databuffer/src/data_buffer.cpp b/services/common/databuffer/src/data_buffer.cpp new file mode 100644 index 00000000..cb6b9387 --- /dev/null +++ b/services/common/databuffer/src/data_buffer.cpp @@ -0,0 +1,52 @@ +/* + * 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 "data_buffer.h" + +#include + +namespace OHOS { +namespace DistributedHardware { +DataBuffer::DataBuffer(size_t capacity) +{ + if (capacity != 0) { + data_ = new (std::nothrow) uint8_t[capacity] {0}; + if (data_ != nullptr) { + capacity_ = capacity; + } + } +} + +DataBuffer::~DataBuffer() +{ + if (data_ != nullptr) { + delete []data_; + data_ = nullptr; + } + + capacity_ = 0; +} + +size_t DataBuffer::Capacity() const +{ + return capacity_; +} + +uint8_t *DataBuffer::Data() const +{ + return data_; +} +} // namespace DistributedHardware +} // namespcae OHOS \ No newline at end of file diff --git a/services/common/screen_channel/include/iscreen_channel.h b/services/common/screen_channel/include/iscreen_channel.h new file mode 100644 index 00000000..b5b06ed8 --- /dev/null +++ b/services/common/screen_channel/include/iscreen_channel.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 OHOS_ISCREEN_CHANNEL_H +#define OHOS_ISCREEN_CHANNEL_H + +#include + +#include "data_buffer.h" +#include "iscreen_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class IScreenChannel { +public: + virtual ~IScreenChannel() = default; + + virtual int32_t CreateSession(const std::shared_ptr &listener) = 0; + virtual int32_t ReleaseSession() = 0; + virtual int32_t OpenSession() = 0; + virtual int32_t CloseSession() = 0; + virtual int32_t SendData(const std::shared_ptr &data) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/screen_channel/include/iscreen_channel_listener.h b/services/common/screen_channel/include/iscreen_channel_listener.h new file mode 100644 index 00000000..1fb3b18f --- /dev/null +++ b/services/common/screen_channel/include/iscreen_channel_listener.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ISCREEN_CHANNEL_LISTENER_H +#define OHOS_ISCREEN_CHANNEL_LISTENER_H + +#include "data_buffer.h" +#include + +namespace OHOS { +namespace DistributedHardware { +class IScreenChannelListener { +public: + virtual ~IScreenChannelListener() = default; + + virtual void OnSessionOpened() = 0; + virtual void OnSessionClosed() = 0; + virtual void OnDataReceived(const std::shared_ptr &data) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/test/unittest/BUILD.gn b/services/common/test/unittest/BUILD.gn new file mode 100644 index 00000000..2f28638c --- /dev/null +++ b/services/common/test/unittest/BUILD.gn @@ -0,0 +1,20 @@ +# 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. + +group("service_common_test") { + testonly = true + deps = [ + "databuffer:data_buffer_test", + "utils:utils_test", + ] +} \ No newline at end of file diff --git a/services/common/test/unittest/databuffer/BUILD.gn b/services/common/test/unittest/databuffer/BUILD.gn new file mode 100644 index 00000000..3303511b --- /dev/null +++ b/services/common/test/unittest/databuffer/BUILD.gn @@ -0,0 +1,68 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/services/data_buffer_test" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${windowmanager_path}/interfaces/innerkits/wm", + "${graphicstandard_path}/interfaces/innerkits/surface", + "${graphicstandard_path}/rosen/modules/render_service_client/core/ui", + "${fwk_common_path}/utils/include", + "${fwk_common_path}/log/include", + "${fwk_utils_path}/include/log", + ] + + include_dirs += [ + "include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/utils/include", + ] +} + +## UnitTest data_buffer_test +ohos_unittest("DataBufferTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/common/test/unittest/databuffer/data_buffer_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${fwk_utils_path}:distributedhardwareutils", + "${graphicstandard_path}/frameworks/surface:surface", + "${graphicstandard_path}/rosen/modules/render_service_client:librender_service_client", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/wm:libwm", + "//foundation/distributedhardware/distributedscreen/services/screentransport/screensinktrans:distributed_screen_sinktrans", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] +} + +group("data_buffer_test") { + testonly = true + deps = [ ":DataBufferTest" ] +} \ No newline at end of file diff --git a/services/common/test/unittest/databuffer/data_buffer_test.cpp b/services/common/test/unittest/databuffer/data_buffer_test.cpp new file mode 100644 index 00000000..fec34599 --- /dev/null +++ b/services/common/test/unittest/databuffer/data_buffer_test.cpp @@ -0,0 +1,59 @@ +/* + * 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 private public +#include "data_buffer_test.h" +#undef private + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void DataBufferTest::SetUpTestCase(void) {} + +void DataBufferTest::TearDownTestCase(void) {} + +void DataBufferTest::SetUp() +{ + dataBuffer_ = std::make_shared(capacity); +} + +void DataBufferTest::TearDown() {} + +/** + * @tc.name: Capacity_001 + * @tc.desc: Verify the Capacity function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DataBufferTest, Capacity_001, TestSize.Level1) +{ + size_t actual = dataBuffer_->Capacity(); + EXPECT_EQ(capacity, actual); +} + +/** + * @tc.name: Data_001 + * @tc.desc: Verify the Data function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(DataBufferTest, Data_001, TestSize.Level1) +{ + uint8_t *actual = dataBuffer_->Data(); + EXPECT_NE(nullptr, actual); +} +} +} \ No newline at end of file diff --git a/services/common/test/unittest/databuffer/data_buffer_test.h b/services/common/test/unittest/databuffer/data_buffer_test.h new file mode 100644 index 00000000..aa75c15d --- /dev/null +++ b/services/common/test/unittest/databuffer/data_buffer_test.h @@ -0,0 +1,33 @@ +/* + * 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 +#include + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +class DataBufferTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + size_t capacity = 1; + std::shared_ptr dataBuffer_ = nullptr; +}; +} +} \ No newline at end of file diff --git a/services/common/test/unittest/utils/BUILD.gn b/services/common/test/unittest/utils/BUILD.gn new file mode 100644 index 00000000..a7fb7152 --- /dev/null +++ b/services/common/test/unittest/utils/BUILD.gn @@ -0,0 +1,70 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/services/utils_test" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "//third_party/json/include", + "${windowmanager_path}/interfaces/innerkits/wm", + "${graphicstandard_path}/interfaces/innerkits/surface", + "${graphicstandard_path}/rosen/modules/render_service_client/core/ui", + "${fwk_common_path}/utils/include", + "${fwk_common_path}/log/include", + "${fwk_utils_path}/include/log", + ] + + include_dirs += [ + "include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/utils/include", + ] +} + +## UnitTest utils_test +ohos_unittest("UtilsTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/common/test/unittest/utils/video_param_test.cpp", + "${services_path}/common/test/unittest/utils/dscreen_maprelation_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${fwk_utils_path}:distributedhardwareutils", + "${graphicstandard_path}/frameworks/surface:surface", + "${graphicstandard_path}/rosen/modules/render_service_client:librender_service_client", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/wm:libwm", + "//foundation/distributedhardware/distributedscreen/services/screenservice/sinkservice:distributed_screen_sink", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] +} + +group("utils_test") { + testonly = true + deps = [ ":UtilsTest" ] +} \ No newline at end of file diff --git a/services/common/test/unittest/utils/dscreen_maprelation_test.cpp b/services/common/test/unittest/utils/dscreen_maprelation_test.cpp new file mode 100644 index 00000000..ec0078f5 --- /dev/null +++ b/services/common/test/unittest/utils/dscreen_maprelation_test.cpp @@ -0,0 +1,97 @@ +/* + * 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 private public +#include "dscreen_maprelation_test.h" +#undef private + +using json = nlohmann::json; + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void DScreenMapRelationTest::SetUpTestCase(void) {} + +void DScreenMapRelationTest::TearDownTestCase(void) {} + +void DScreenMapRelationTest::SetUp() +{ + dscreenMapRelation = std::make_shared(); +} + +void DScreenMapRelationTest::TearDown() {} + +/** + * @tc.name: GetDisplayId_001 + * @tc.desc: Verify the GetDisplayId function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ + HWTEST_F(DScreenMapRelationTest, GetDisplayId_001, TestSize.Level1) +{ + uint64_t displayId = 0; + dscreenMapRelation->SetDisplayId(displayId); + uint64_t actual = dscreenMapRelation->GetDisplayId(); + EXPECT_EQ(displayId, actual); +} + +/** + * @tc.name: GetScreenId_001 + * @tc.desc: Verify the GetScreenId function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ + HWTEST_F(DScreenMapRelationTest, GetScreenId_001, TestSize.Level1) +{ + uint64_t screenId = 0; + dscreenMapRelation->SetScreenId(screenId); + uint64_t actual = dscreenMapRelation->GetScreenId(); + EXPECT_EQ(screenId, actual); +} + +/** + * @tc.name: GetDisplayRect_001 + * @tc.desc: Verify the GetDisplayRect function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ + HWTEST_F(DScreenMapRelationTest, GetDisplayRect_001, TestSize.Level1) +{ + DisplayRect res; + int32_t startX = 10; + res.startX = startX; + dscreenMapRelation->SetDisplayRect(res); + DisplayRect actual = dscreenMapRelation->GetDisplayRect(); + EXPECT_EQ(startX, actual.startX); +} + +/** + * @tc.name: GetScreenRect_001 + * @tc.desc: Verify the GetScreenRect function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ + HWTEST_F(DScreenMapRelationTest, GetScreenRect_001, TestSize.Level1) +{ + ScreenRect res; + int32_t startX = 10; + res.startX = startX; + dscreenMapRelation->SetScreenRect(res); + ScreenRect actual = dscreenMapRelation->GetScreenRect(); + EXPECT_EQ(startX, actual.startX); +} +} +} \ No newline at end of file diff --git a/services/common/test/unittest/utils/dscreen_maprelation_test.h b/services/common/test/unittest/utils/dscreen_maprelation_test.h new file mode 100644 index 00000000..98069114 --- /dev/null +++ b/services/common/test/unittest/utils/dscreen_maprelation_test.h @@ -0,0 +1,35 @@ +/* + * 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 + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_maprelation.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +class DScreenMapRelationTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr dscreenMapRelation = nullptr; +}; +} +} \ No newline at end of file diff --git a/services/common/test/unittest/utils/video_param_test.cpp b/services/common/test/unittest/utils/video_param_test.cpp new file mode 100644 index 00000000..78052b97 --- /dev/null +++ b/services/common/test/unittest/utils/video_param_test.cpp @@ -0,0 +1,135 @@ +/* + * 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 private public +#include "video_param_test.h" +#undef private + +using json = nlohmann::json; + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void VideoParamTest::SetUpTestCase(void) {} + +void VideoParamTest::TearDownTestCase(void) {} + +void VideoParamTest::SetUp() +{ + videoParam_ = std::make_shared(); +} + +void VideoParamTest::TearDown() {} + +/** + * @tc.name: GetScreenWidth_001 + * @tc.desc: Verify the GetScreenWidth function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetScreenWidth_001, TestSize.Level1) +{ + uint32_t screenWidth = 1; + videoParam_->SetScreenWidth(screenWidth); + uint32_t actual = videoParam_->GetScreenWidth(); + EXPECT_EQ(screenWidth, actual); +} + +/** + * @tc.name: GetScreenHeight_001 + * @tc.desc: Verify the GetScreenHeight function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetScreenHeight_001, TestSize.Level1) +{ + uint32_t screenHeight = 1; + videoParam_->SetScreenHeight(screenHeight); + uint32_t actual = videoParam_->GetScreenHeight(); + EXPECT_EQ(screenHeight, actual); +} + +/** + * @tc.name: GetVideoWidth_001 + * @tc.desc: Verify the GetVideoWidth function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetVideoWidth_001, TestSize.Level1) +{ + uint32_t videoWidth = 1; + videoParam_->SetVideoWidth(videoWidth); + uint32_t actual = videoParam_->GetVideoWidth(); + EXPECT_EQ(videoWidth, actual); +} + +/** + * @tc.name: GetVideoHeight_001 + * @tc.desc: Verify the GetVideoHeight function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetVideoHeight_001, TestSize.Level1) +{ + uint32_t videoHeight = 1; + videoParam_->SetVideoHeight(videoHeight); + uint32_t actual = videoParam_->GetVideoHeight(); + EXPECT_EQ(videoHeight, actual); +} + +/** + * @tc.name: GetFps_001 + * @tc.desc: Verify the GetFps function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetFps_001, TestSize.Level1) +{ + uint32_t fps = 1; + videoParam_->SetFps(fps); + uint32_t actual = videoParam_->GetFps(); + EXPECT_EQ(fps, actual); +} + +/** + * @tc.name: GetCodecType_001 + * @tc.desc: Verify the GetCodecType function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetCodecType_001, TestSize.Level1) +{ + uint8_t codecType = 1; + videoParam_->SetCodecType(codecType); + uint8_t actual = videoParam_->GetCodecType(); + EXPECT_EQ(codecType, actual); +} + +/** + * @tc.name: GetVideoFormat_001 + * @tc.desc: Verify the GetVideoFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(VideoParamTest, GetVideoFormat_001, TestSize.Level1) +{ + uint8_t videoFormat = 1; + videoParam_->SetVideoFormat(videoFormat); + uint8_t actual = videoParam_->GetVideoFormat(); + EXPECT_EQ(videoFormat, actual); +} +} +} \ No newline at end of file diff --git a/services/common/test/unittest/utils/video_param_test.h b/services/common/test/unittest/utils/video_param_test.h new file mode 100644 index 00000000..d5877799 --- /dev/null +++ b/services/common/test/unittest/utils/video_param_test.h @@ -0,0 +1,35 @@ +/* + * 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 + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "video_param.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +class VideoParamTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr videoParam_ = nullptr; +}; +} +} \ No newline at end of file diff --git a/services/common/utils/include/dscreen_maprelation.h b/services/common/utils/include/dscreen_maprelation.h new file mode 100644 index 00000000..25c44027 --- /dev/null +++ b/services/common/utils/include/dscreen_maprelation.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_MAP_RELATION_H +#define OHOS_DSCREEN_MAP_RELATION_H + +#include "nlohmann/json.hpp" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +struct ScreenRect { + int32_t startX; + int32_t startY; + uint16_t width; + uint16_t height; +}; +struct DisplayRect { + int32_t startX; + int32_t startY; + int32_t width; + int32_t height; +}; + +class DScreenMapRelation { +public: + void SetDisplayId(uint64_t displayId); + uint64_t GetDisplayId() const; + void SetScreenId(uint64_t screenId); + uint64_t GetScreenId() const; + void SetDisplayRect(const DisplayRect &displayRect); + DisplayRect& GetDisplayRect(); + void SetScreenRect(const ScreenRect &screenRect); + ScreenRect& GetScreenRect(); +private: + friend void to_json(json &j, const DScreenMapRelation &dScreenMapRelation); + friend void from_json(const json &j, DScreenMapRelation &dScreenMapRelation); + + uint64_t displayId_; + uint64_t screenId_; + DisplayRect displayRect_; + ScreenRect screenRect_; +}; +void to_json(const json &j, const DScreenMapRelation &dScreenMapRelation); +void from_json(const json &j, DScreenMapRelation &dScreenMapRelation); +void to_json(json &j, const DisplayRect &rect); +void to_json(json &j, const ScreenRect &rect); +void from_json(const json &j, DisplayRect &rect); +void from_json(const json &j, ScreenRect &rect); +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/utils/include/video_param.h b/services/common/utils/include/video_param.h new file mode 100644 index 00000000..3db42ee2 --- /dev/null +++ b/services/common/utils/include/video_param.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_VIDEO_PARAM_H +#define OHOS_DSCREEN_VIDEO_PARAM_H + +#include "nlohmann/json.hpp" + +#include "dscreen_constants.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +class VideoParam { +public: + void SetScreenWidth(uint32_t screenWidth); + uint32_t GetScreenWidth() const; + void SetScreenHeight(uint32_t screenHeight); + uint32_t GetScreenHeight() const; + void SetVideoWidth(uint32_t videoWidth); + uint32_t GetVideoWidth() const; + void SetVideoHeight(uint32_t videoHeight); + uint32_t GetVideoHeight() const; + void SetFps(uint32_t fps); + uint32_t GetFps() const; + void SetCodecType(uint8_t codecType); + uint8_t GetCodecType() const; + void SetVideoFormat(uint8_t videoFormat); + uint8_t GetVideoFormat() const; +private: + friend void to_json(json &j, const VideoParam &videoParam); + friend void from_json(const json &j, VideoParam &videoParam); + + uint32_t screenWidth_; + uint32_t screenHeight_; + uint32_t videoWidth_; + uint32_t videoHeight_; + uint32_t fps_ = DEFAULT_FPS; + uint8_t codecType_ = DEFAULT_CODECTYPE; + uint8_t videoFormat_ = DEFAULT_VIDEO_FORMAT; +}; +void to_json(json &j, const VideoParam &videoParam); +void from_json(const json &j, VideoParam &videoParam); +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/utils/src/dscreen_maprelation.cpp b/services/common/utils/src/dscreen_maprelation.cpp new file mode 100644 index 00000000..28db6e2e --- /dev/null +++ b/services/common/utils/src/dscreen_maprelation.cpp @@ -0,0 +1,123 @@ +/* + * 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 "dscreen_maprelation.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +void DScreenMapRelation::SetDisplayId(uint64_t displayId) +{ + displayId_ = displayId; +} + +uint64_t DScreenMapRelation::GetDisplayId() const +{ + return displayId_; +} + +void DScreenMapRelation::SetScreenId(uint64_t screenId) +{ + screenId_ = screenId; +} + +uint64_t DScreenMapRelation::GetScreenId() const +{ + return screenId_; +} + +void DScreenMapRelation::SetDisplayRect(const DisplayRect &displayRect) +{ + displayRect_ = displayRect; +} + +DisplayRect& DScreenMapRelation::GetDisplayRect() +{ + return displayRect_; +} + +void DScreenMapRelation::SetScreenRect(const ScreenRect &screenRect) +{ + screenRect_ = screenRect; +} + +ScreenRect& DScreenMapRelation::GetScreenRect() +{ + return screenRect_; +} + +void to_json(json &j, const DScreenMapRelation &dScreenMapRelation) +{ + json displayRectJson; + json screenRectJson; + to_json(displayRectJson, dScreenMapRelation.displayRect_); + to_json(screenRectJson, dScreenMapRelation.screenRect_); + j = json { + {KEY_DISPLAY_ID, dScreenMapRelation.displayId_}, + {KEY_SCREEN_ID, dScreenMapRelation.screenId_}, + {KEY_DISPLAY_RECT, displayRectJson}, + {KEY_SCREEN_RECT, screenRectJson} + }; +} + +void from_json(const json &j, DScreenMapRelation &dScreenMapRelation) +{ + j.at(KEY_DISPLAY_ID).get_to(dScreenMapRelation.displayId_); + j.at(KEY_SCREEN_ID).get_to(dScreenMapRelation.screenId_); + from_json(j.at(KEY_DISPLAY_RECT), dScreenMapRelation.displayRect_); + from_json(j.at(KEY_SCREEN_RECT), dScreenMapRelation.screenRect_); +} + +void to_json(json &j, const DisplayRect &rect) +{ + j = json { + {KEY_POINT_START_X, rect.startX}, + {KEY_POINT_START_Y, rect.startY}, + {KEY_WIDTH, rect.width}, + {KEY_HEIGHT, rect.height} + }; +} + +void from_json(const json &j, DisplayRect &rect) +{ + j.at(KEY_POINT_START_X).get_to(rect.startX); + j.at(KEY_POINT_START_Y).get_to(rect.startY); + j.at(KEY_WIDTH).get_to(rect.width); + j.at(KEY_HEIGHT).get_to(rect.height); +} + +void to_json(json &j, const ScreenRect &rect) +{ + j = json { + {KEY_POINT_START_X, rect.startX}, + {KEY_POINT_START_Y, rect.startY}, + {KEY_WIDTH, rect.width}, + {KEY_HEIGHT, rect.height} + }; +} + +void from_json(const json &j, ScreenRect &rect) +{ + j.at(KEY_POINT_START_X).get_to(rect.startX); + j.at(KEY_POINT_START_Y).get_to(rect.startY); + j.at(KEY_WIDTH).get_to(rect.width); + j.at(KEY_HEIGHT).get_to(rect.height); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/common/utils/src/video_param.cpp b/services/common/utils/src/video_param.cpp new file mode 100644 index 00000000..6e1f420d --- /dev/null +++ b/services/common/utils/src/video_param.cpp @@ -0,0 +1,116 @@ +/* + * 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 "video_param.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +void VideoParam::SetScreenWidth(uint32_t screenWidth) +{ + screenWidth_ = screenWidth; +} + +uint32_t VideoParam::GetScreenWidth() const +{ + return screenWidth_; +} + +void VideoParam::SetScreenHeight(uint32_t screenHeight) +{ + screenHeight_ = screenHeight; +} + +uint32_t VideoParam::GetScreenHeight() const +{ + return screenHeight_; +} + +void VideoParam::SetVideoWidth(uint32_t videoWidth) +{ + videoWidth_ = videoWidth; +} + +uint32_t VideoParam::GetVideoWidth() const +{ + return videoWidth_; +} + +void VideoParam::SetVideoHeight(uint32_t videoHeight) +{ + videoHeight_ = videoHeight; +} + +uint32_t VideoParam::GetVideoHeight() const +{ + return videoHeight_; +} + +void VideoParam::SetFps(uint32_t fps) +{ + fps_ = fps; +} + +uint32_t VideoParam::GetFps() const +{ + return fps_; +} + +void VideoParam::SetCodecType(uint8_t codecType) +{ + codecType_ = codecType; +} + +uint8_t VideoParam::GetCodecType() const +{ + return codecType_; +} + +void VideoParam::SetVideoFormat(uint8_t videoFormat) +{ + videoFormat_ = videoFormat; +} + +uint8_t VideoParam::GetVideoFormat() const +{ + return videoFormat_; +} + +void to_json(json &j, const DistributedHardware::VideoParam &videoParam) +{ + j = json { + {KEY_SCREEN_WIDTH, videoParam.screenWidth_}, + {KEY_SCREEN_HEIGHT, videoParam.screenHeight_}, + {KEY_VIDEO_WIDTH, videoParam.videoWidth_}, + {KEY_VIDEO_HEIGHT, videoParam.videoHeight_}, + {KEY_FPS, videoParam.fps_}, + {KEY_CODECTYPE, videoParam.codecType_} + }; +} + +void from_json(const json &j, DistributedHardware::VideoParam &videoParam) +{ + j.at(KEY_SCREEN_WIDTH).get_to(videoParam.screenWidth_); + j.at(KEY_SCREEN_HEIGHT).get_to(videoParam.screenHeight_); + j.at(KEY_VIDEO_WIDTH).get_to(videoParam.videoWidth_); + j.at(KEY_VIDEO_HEIGHT).get_to(videoParam.videoHeight_); + j.at(KEY_FPS).get_to(videoParam.fps_); + j.at(KEY_CODECTYPE).get_to(videoParam.codecType_); +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/screenclient/BUILD.gn b/services/screenclient/BUILD.gn new file mode 100644 index 00000000..603c6378 --- /dev/null +++ b/services/screenclient/BUILD.gn @@ -0,0 +1,59 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_client") { + + include_dirs = [ + "${windowmanager_path}/interfaces/innerkits/wm", + "${graphicstandard_path}/interfaces/innerkits/surface", + "${graphicstandard_path}/rosen/modules/render_service_client/core/ui", + "${fwk_common_path}/utils/include", + "//foundation/multimodalinput/input/interfaces/native/innerkits/event/include/" + ] + + include_dirs += [ + "include", + "${common_path}/include", + ] + + sources = [ + "${services_path}/screenclient/src/screen_client.cpp", + "${services_path}/screenclient/src/screen_client_window_adapter.cpp", + ] + + deps = [ + "${common_path}:distributed_screen_utils", + "${graphicstandard_path}/frameworks/surface:surface", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/wm:libwm", + "//foundation/multimodalinput/input:mmi_uinject", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreenclient\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + part_name = "distributed_screen" + subsystem_name = "distributedhardware" +} + diff --git a/services/screenclient/include/screen_client.h b/services/screenclient/include/screen_client.h new file mode 100644 index 00000000..be3e8f99 --- /dev/null +++ b/services/screenclient/include/screen_client.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_CLIENT_H +#define OHOS_SCREEN_CLIENT_H + +#include +#include +#include +#include +#include +#include +#include + +#include "single_instance.h" +#include "surface.h" + +#include "dscreen_constants.h" +#include "screen_client_common.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenClient { +DECLARE_SINGLE_INSTANCE_BASE(ScreenClient); +public: + int32_t AddWindow(std::shared_ptr windowProperty); + sptr GetSurface(int32_t windowId); + int32_t ShowWindow(int32_t windowId); + int32_t MoveWindow(int32_t windowId, int32_t startX, int32_t startY); + int32_t RemoveWindow(int32_t windowId); + int32_t HideWindow(int32_t windowId); +private: + ScreenClient() = default; + ~ScreenClient(); + std::map> surfaceMap_; + std::atomic windowId_ = INVALID_WINDOW_ID; + std::mutex surfaceMapMutex_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenclient/include/screen_client_common.h b/services/screenclient/include/screen_client_common.h new file mode 100644 index 00000000..431cc212 --- /dev/null +++ b/services/screenclient/include/screen_client_common.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_CLIENT_COMMON_H +#define OHOS_DSCREEN_CLIENT_COMMON_H + +namespace OHOS { +namespace DistributedHardware { +struct WindowProperty { + int32_t type; + uint64_t displayId; + int32_t startX; + int32_t startY; + uint16_t width; + uint16_t height; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif diff --git a/services/screenclient/include/screen_client_window_adapter.h b/services/screenclient/include/screen_client_window_adapter.h new file mode 100644 index 00000000..80347e60 --- /dev/null +++ b/services/screenclient/include/screen_client_window_adapter.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_CLIENT_WINDOW_H +#define OHOS_SCREEN_CLIENT_WINDOW_H + +#include +#include +#include +#include +#include + +#include "i_input_event_consumer.h" +#include "single_instance.h" +#include "surface.h" +#include "window.h" + +#include "screen_client.h" +#include "screen_client_common.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenClientWindowAdapter { +DECLARE_SINGLE_INSTANCE_BASE(ScreenClientWindowAdapter); +public: + sptr CreateWindow(std::shared_ptr windowProperty, int32_t windowId); + int32_t ShowWindow(int32_t windowId); + int32_t HideWindow(int32_t windowId); + int32_t MoveWindow(int32_t windowId, int32_t startX, int32_t startY); + int32_t RemoveWindow(int32_t windowId); +private: + ScreenClientWindowAdapter() = default; + ~ScreenClientWindowAdapter(); + std::map> windowIdMap_; + std::mutex windowIdMapMutex_; +}; + +class ScreenClientInputEventListener : public RefBase, public MMI::IInputEventConsumer { +public: + ScreenClientInputEventListener() = default; + void OnInputEvent(std::shared_ptr pointerEvent) const override; + void OnInputEvent(std::shared_ptr keyEvent) const override; + void OnInputEvent(std::shared_ptr axisEvent) const override; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenclient/src/screen_client.cpp b/services/screenclient/src/screen_client.cpp new file mode 100644 index 00000000..a2b17115 --- /dev/null +++ b/services/screenclient/src/screen_client.cpp @@ -0,0 +1,162 @@ +/* + * 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 "screen_client.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "screen_client_window_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(ScreenClient); + +ScreenClient::~ScreenClient() +{ + DHLOGD("~ScreenClient"); + { + std::lock_guard dataLock(surfaceMapMutex_); + for (const auto &item : surfaceMap_) { + int32_t ret = ScreenClientWindowAdapter::GetInstance().RemoveWindow(item.first); + if (ret != DH_SUCCESS) { + DHLOGE("windowId (ID = %d) remove failed.", item.first); + return; + } + } + surfaceMap_.clear(); + windowId_ = INVALID_WINDOW_ID; + } + DHLOGD("ScreenClient Destory."); + return; +} + +int32_t ScreenClient::AddWindow(std::shared_ptr windowProperty) +{ + if (windowProperty == nullptr) { + DHLOGE("windowProperty is nullptr."); + return ERR_DH_SCREEN_SCREENCLIENT_ADD_WINDOW_ERROR; + } + int32_t windowId = ++windowId_; + sptr surface = ScreenClientWindowAdapter::GetInstance().CreateWindow(windowProperty, windowId); + if (surface == nullptr) { + DHLOGE("Surface is nullptr."); + return ERR_DH_SCREEN_SCREENCLIENT_ADD_WINDOW_ERROR; + } + { + std::lock_guard dataLock(surfaceMapMutex_); + surfaceMap_.emplace(windowId, surface); + } + DHLOGI("Add window (ID = %d) success.", windowId); + return windowId; +} + +int32_t ScreenClient::ShowWindow(int32_t windowId) +{ + { + std::lock_guard dataLock(surfaceMapMutex_); + auto iter = surfaceMap_.find(windowId); + if (iter == surfaceMap_.end()) { + DHLOGE("windowId (ID = %d) is non-existent.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR; + } + } + int32_t ret = ScreenClientWindowAdapter::GetInstance().ShowWindow(windowId); + if (DH_SUCCESS != ret) { + DHLOGE("Show window (ID = %d) failed.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR; + } + DHLOGI("Show window (ID = %d) success.", windowId); + return ret; +} + +int32_t ScreenClient::HideWindow(int32_t windowId) +{ + { + std::lock_guard dataLock(surfaceMapMutex_); + auto iter = surfaceMap_.find(windowId); + if (iter == surfaceMap_.end()) { + DHLOGE("windowId (ID = %d) is non-existent.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR; + } + } + int32_t ret = ScreenClientWindowAdapter::GetInstance().HideWindow(windowId); + if (DH_SUCCESS != ret) { + DHLOGE("Hide window (ID = %d) failed.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR; + } + DHLOGI("Hide window (ID = %d) success.", windowId); + return ret; +} + +int32_t ScreenClient::MoveWindow(int32_t windowId, int32_t startX, int32_t startY) +{ + { + std::lock_guard dataLock(surfaceMapMutex_); + auto iter = surfaceMap_.find(windowId); + if (iter == surfaceMap_.end()) { + DHLOGE("windowId (ID = %d) is non-existent.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR; + } + } + int32_t ret = ScreenClientWindowAdapter::GetInstance().MoveWindow(windowId, startX, startY); + if (DH_SUCCESS != ret) { + DHLOGE("Move window (ID = %d) failed.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR; + } + DHLOGD("Move window (ID = %d) success.", windowId); + return ret; +} + +sptr ScreenClient::GetSurface(int32_t windowId) +{ + sptr surface = nullptr; + { + std::lock_guard dataLock(surfaceMapMutex_); + auto iter = surfaceMap_.find(windowId); + if (iter == surfaceMap_.end()) { + DHLOGE("windowId (ID = %d) is non-existent.", windowId); + return nullptr; + } + surface = iter->second; + } + if (surface == nullptr) { + DHLOGE("Get surface is null(ID = %d).", windowId); + return nullptr; + } + DHLOGD("Get surface (ID = %d) success.", windowId); + return surface; +} + +int32_t ScreenClient::RemoveWindow(int32_t windowId) +{ + { + std::lock_guard dataLock(surfaceMapMutex_); + auto iter = surfaceMap_.find(windowId); + if (iter == surfaceMap_.end()) { + DHLOGE("windowId (ID = %d) is non-existent.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + surfaceMap_.erase(windowId); + } + int32_t ret = ScreenClientWindowAdapter::GetInstance().RemoveWindow(windowId); + if (ret != DH_SUCCESS) { + DHLOGE("windowId (ID = %d) remove failed.", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + DHLOGD("windowId (ID = %d) remove success.", windowId); + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenclient/src/screen_client_window_adapter.cpp b/services/screenclient/src/screen_client_window_adapter.cpp new file mode 100644 index 00000000..9e3eb78c --- /dev/null +++ b/services/screenclient/src/screen_client_window_adapter.cpp @@ -0,0 +1,215 @@ +/* + * 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 "screen_client_window_adapter.h" + +#include "rs_surface_node.h" +#include "window_option.h" +#include "wm_common.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(ScreenClientWindowAdapter); +ScreenClientWindowAdapter::~ScreenClientWindowAdapter() +{ + DHLOGD("~ScreenClientWindowAdapter"); + { + std::lock_guard dataLock(windowIdMapMutex_); + for (const auto &item : windowIdMap_) { + auto window = item.second; + if (window == nullptr) { + DHLOGE("window is nullptr(windowId = %d).", item.first); + return; + } + if (OHOS::Rosen::WMError::WM_OK != window->Destroy()) { + DHLOGE("screenclientSurface is nullptr(windowId = %d).", item.first); + return; + } + } + windowIdMap_.clear(); + } + DHLOGD("ScreenClientWindowAdapter Destory."); + return; +} + +sptr ScreenClientWindowAdapter::CreateWindow(std::shared_ptr windowProperty, + int32_t windowId) +{ + if (windowProperty == nullptr) { + DHLOGE("windowProperty is nullptr."); + return nullptr; + } + sptr option = new Rosen::WindowOption(); + option->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_LAUNCHING); + option->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + option->SetDisplayId(windowProperty->displayId); + std::string windowName = SCREEN_CLIENT_WINDOW + std::to_string(windowId); + sptr window = Rosen::Window::Create(windowName, option); + if (window == nullptr || window->GetSurfaceNode() == nullptr) { + DHLOGE("Create screen client window failed."); + return nullptr; + } + auto surface = window->GetSurfaceNode()->GetSurface(); + if (surface == nullptr) { + window->Destroy(); + DHLOGE("surface is nullptr"); + return nullptr; + } + std::shared_ptr listener = + std::make_shared(ScreenClientInputEventListener()); + window->AddInputEventListener(listener); + DHLOGD("Create window name is %s.", windowName.c_str()); + if (OHOS::Rosen::WMError::WM_OK != window->Resize(windowProperty->width, windowProperty->height)) { + window->Destroy(); + DHLOGE("Window resize failed."); + return nullptr; + } + if (OHOS::Rosen::WMError::WM_OK != window->MoveTo(windowProperty->startX, windowProperty->startY)) { + window->Destroy(); + DHLOGE("Window moveto failed."); + return nullptr; + } + { + std::lock_guard dataLock(windowIdMapMutex_); + windowIdMap_.emplace(windowId, window); + } + DHLOGD("Get surface(windowId = %d) success.", windowId); + return surface; +} + +int32_t ScreenClientWindowAdapter::ShowWindow(int32_t windowId) +{ + sptr window = nullptr; + { + std::lock_guard dataLock(windowIdMapMutex_); + auto iter = windowIdMap_.find(windowId); + if (iter == windowIdMap_.end()) { + DHLOGE("ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR."); + return ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR; + } + window = iter->second; + } + if (window == nullptr) { + DHLOGE("Current window is null."); + return ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR; + } + if (OHOS::Rosen::WMError::WM_OK != window->Show()) { + DHLOGE("Show window failed."); + return ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR; + } + DHLOGD("Show window (windowId = %d) success.", windowId); + return DH_SUCCESS; +} + +int32_t ScreenClientWindowAdapter::HideWindow(int32_t windowId) +{ + sptr window = nullptr; + { + std::lock_guard dataLock(windowIdMapMutex_); + auto iter = windowIdMap_.find(windowId); + if (iter == windowIdMap_.end()) { + DHLOGE("ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR."); + return ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR; + } + window = iter->second; + } + if (window == nullptr) { + DHLOGE("Current window is null."); + return ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR; + } + if (OHOS::Rosen::WMError::WM_OK != window->Hide()) { + DHLOGE("Hide window failed."); + return ERR_DH_SCREEN_SCREENCLIENT_HIDE_WINDOW_ERROR; + } + DHLOGD("Hide window (windowId = %d) success.", windowId); + return DH_SUCCESS; +} + +int32_t ScreenClientWindowAdapter::MoveWindow(int32_t windowId, int32_t startX, int32_t startY) +{ + sptr window = nullptr; + { + std::lock_guard dataLock(windowIdMapMutex_); + auto iter = windowIdMap_.find(windowId); + if (iter == windowIdMap_.end()) { + DHLOGE("Invalid windowId (windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR; + } + window = iter->second; + } + if (window == nullptr) { + DHLOGE("Current window is null(windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR; + } + if (OHOS::Rosen::WMError::WM_OK != window->MoveTo(startX, startY)) { + DHLOGE("Move window failed (windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR; + } + DHLOGD("MoveTo window (windowId = %d) success.", windowId); + return DH_SUCCESS; +} + +int32_t ScreenClientWindowAdapter::RemoveWindow(int32_t windowId) +{ + sptr window = nullptr; + { + std::lock_guard dataLock(windowIdMapMutex_); + auto iter = windowIdMap_.find(windowId); + if (iter == windowIdMap_.end()) { + DHLOGE("Invalid windowId(windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + window = iter->second; + windowIdMap_.erase(windowId); + } + if (window == nullptr) { + DHLOGE("Current window is null(windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + if (OHOS::Rosen::WMError::WM_OK != window->Hide()) { + DHLOGE("Remove window window failed(windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + if (OHOS::Rosen::WMError::WM_OK != window->Destroy()) { + DHLOGE("Remove window window failed(windowId = %d).", windowId); + return ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR; + } + DHLOGD("Remove window success(windowId = %d).", windowId); + return DH_SUCCESS; +} + +void ScreenClientInputEventListener::OnInputEvent(std::shared_ptr pointerEvent) const +{ + DHLOGI("onInputEvent, pointerEvent"); + pointerEvent->MarkProcessed(); +} + +void ScreenClientInputEventListener::OnInputEvent(std::shared_ptr keyEvent) const +{ + DHLOGI("onInputEvent, keyEvent"); + keyEvent->MarkProcessed(); +} + +void ScreenClientInputEventListener::OnInputEvent(std::shared_ptr axisEvent) const +{ + DHLOGI("onInputEvent, axisEvent"); + axisEvent->MarkProcessed(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenclient/test/unittest/BUILD.gn b/services/screenclient/test/unittest/BUILD.gn new file mode 100644 index 00000000..4becb3d9 --- /dev/null +++ b/services/screenclient/test/unittest/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/screen_client_test" + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${windowmanager_path}/interfaces/innerkits/wm", + "${graphicstandard_path}/interfaces/innerkits/surface", + "${graphicstandard_path}/rosen/modules/render_service_client/core/ui", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/log", + ] + + include_dirs += [ + "include", + "${common_path}/include", + "${services_path}/screenclient/include", + "${services_path}/screenclient/test/unittest/include", + ] +} + +## UnitTest screen_client_test +ohos_unittest("ScreenClientTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/screenclient/test/unittest/src/screen_client_test.cpp", + "${services_path}/screenclient/test/unittest/src/screen_client_window_adapter_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${fwk_utils_path}:distributedhardwareutils", + "${graphicstandard_path}/frameworks/surface:surface", + "${graphicstandard_path}/rosen/modules/render_service_client:librender_service_client", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/wm:libwm", + "//foundation/distributedhardware/distributedscreen/services/screenclient:distributed_screen_client", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] +} + +group("screen_client_test") { + testonly = true + deps = [ ":ScreenClientTest" ] +} + diff --git a/services/screenclient/test/unittest/include/screen_client_test.h b/services/screenclient/test/unittest/include/screen_client_test.h new file mode 100644 index 00000000..d085267a --- /dev/null +++ b/services/screenclient/test/unittest/include/screen_client_test.h @@ -0,0 +1,33 @@ +/* + * 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 + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "screen_client.h" +#include "screen_client_window_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenClientTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +} +} \ No newline at end of file diff --git a/services/screenclient/test/unittest/include/screen_client_window_adapter_test.h b/services/screenclient/test/unittest/include/screen_client_window_adapter_test.h new file mode 100644 index 00000000..1b222a5e --- /dev/null +++ b/services/screenclient/test/unittest/include/screen_client_window_adapter_test.h @@ -0,0 +1,37 @@ +/* + * 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 + +#include "rs_surface_node.h" +#include "window_option.h" +#include "wm_common.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "screen_client_window_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenClientWindowAdapterTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +} +} \ No newline at end of file diff --git a/services/screenclient/test/unittest/src/screen_client_test.cpp b/services/screenclient/test/unittest/src/screen_client_test.cpp new file mode 100644 index 00000000..859df30d --- /dev/null +++ b/services/screenclient/test/unittest/src/screen_client_test.cpp @@ -0,0 +1,171 @@ +/* + * 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 private public +#include "screen_client_test.h" +#undef private + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ScreenClientTest::SetUpTestCase(void) {} + +void ScreenClientTest::TearDownTestCase(void) {} + +void ScreenClientTest::SetUp() {} + +void ScreenClientTest::TearDown() {} + +/** + * @tc.name: ShowWindow_001 + * @tc.desc: Verify the ShowWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, ShowWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t actual = ScreenClient::GetInstance().ShowWindow(windowId); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR, actual); +} + +/** + * @tc.name: ShowWindow_002 + * @tc.desc: Verify the ShowWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, ShowWindow_002, TestSize.Level1) +{ + std::shared_ptr windowProperty = std::make_shared(); + ScreenClient::GetInstance().windowId_ = 0; + int32_t windowId = ScreenClient::GetInstance().AddWindow(windowProperty); + int32_t actual = ScreenClient::GetInstance().ShowWindow(windowId); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: AddWindow_001 + * @tc.desc: Verify the AddWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, AddWindow_001, TestSize.Level1) +{ + std::shared_ptr windowProperty = nullptr; + int32_t actual = ScreenClient::GetInstance().AddWindow(windowProperty); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_ADD_WINDOW_ERROR, actual); +} + +/** + * @tc.name: AddWindow_002 + * @tc.desc: Verify the AddWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, AddWindow_002, TestSize.Level1) +{ + std::shared_ptr windowProperty = std::make_shared(); + ScreenClient::GetInstance().windowId_ = 2; + int32_t actual = ScreenClient::GetInstance().AddWindow(windowProperty); + EXPECT_EQ(3, actual); +} + +/** + * @tc.name: MoveWindow_001 + * @tc.desc: Verify the MoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, MoveWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t startX = 0; + int32_t startY = 0; + int32_t actual = ScreenClient::GetInstance().MoveWindow(windowId, startX, startY); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR, actual); +} + +/** + * @tc.name: MoveWindow_002 + * @tc.desc: Verify the MoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, MoveWindow_002, TestSize.Level1) +{ + int32_t windowId = 1; + int32_t startX = 0; + int32_t startY = 0; + int32_t actual = ScreenClient::GetInstance().MoveWindow(windowId, startX, startY); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: RemoveWindow_001 + * @tc.desc: Verify the RemoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, RemoveWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t actual = ScreenClient::GetInstance().RemoveWindow(windowId); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR, actual); +} + +/** + * @tc.name: RemoveWindow_002 + * @tc.desc: Verify the RemoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, RemoveWindow_002, TestSize.Level1) +{ + int32_t windowId = 1; + int32_t actual = ScreenClient::GetInstance().RemoveWindow(windowId); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: GetSurface_001 + * @tc.desc: Verify the GetSurface function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, GetSurface_001, TestSize.Level1) +{ + int32_t windowId = 0; + sptr actualSurface = ScreenClient::GetInstance().GetSurface(windowId); + EXPECT_EQ(nullptr, actualSurface); +} + +/** + * @tc.name: GetSurface_002 + * @tc.desc: Verify the GetSurface function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientTest, GetSurface_002, TestSize.Level1) +{ + std::shared_ptr windowProperty = std::make_shared(); + ScreenClient::GetInstance().windowId_ = 0; + int32_t windowId = ScreenClient::GetInstance().AddWindow(windowProperty); + sptr actualSurface = ScreenClient::GetInstance().GetSurface(windowId); + EXPECT_NE(nullptr, actualSurface); +} +} +} \ No newline at end of file diff --git a/services/screenclient/test/unittest/src/screen_client_window_adapter_test.cpp b/services/screenclient/test/unittest/src/screen_client_window_adapter_test.cpp new file mode 100644 index 00000000..464b9dd8 --- /dev/null +++ b/services/screenclient/test/unittest/src/screen_client_window_adapter_test.cpp @@ -0,0 +1,143 @@ +/* + * 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 private public +#include "screen_client_window_adapter_test.h" +#undef private + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ScreenClientWindowAdapterTest::SetUpTestCase(void) {} + +void ScreenClientWindowAdapterTest::TearDownTestCase(void) {} + +void ScreenClientWindowAdapterTest::SetUp() {} + +void ScreenClientWindowAdapterTest::TearDown() {} + +/** + * @tc.name: CreateWindow_001 + * @tc.desc: Verify the CreateWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, CreateWindow_001, TestSize.Level1) +{ + std::shared_ptr windowProperty = nullptr; + int32_t windowId = 0; + sptr actualSurface = ScreenClientWindowAdapter::GetInstance().CreateWindow(windowProperty, windowId); + EXPECT_EQ(nullptr, actualSurface); +} + +/** + * @tc.name: CreateWindow_002 + * @tc.desc: Verify the CreateWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, CreateWindow_002, TestSize.Level1) +{ + std::shared_ptr windowProperty = std::make_shared(); + int32_t windowId = 2; + sptr surface = nullptr; + sptr actualSurface = ScreenClientWindowAdapter::GetInstance().CreateWindow(windowProperty, windowId); + EXPECT_NE(surface, actualSurface); +} + +/** + * @tc.name: ShowWindow_001 + * @tc.desc: Verify the ShowWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, ShowWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t actual = ScreenClientWindowAdapter::GetInstance().ShowWindow(windowId); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_SHOW_WINDOW_ERROR, actual); +} + +/** + * @tc.name: ShowWindow_002 + * @tc.desc: Verify the ShowWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, ShowWindow_002, TestSize.Level1) +{ + int32_t windowId = 1; + int32_t actual = ScreenClientWindowAdapter::GetInstance().ShowWindow(windowId); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: MoveWindow_001 + * @tc.desc: Verify the MoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, MoveWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t startX = 0; + int32_t startY = 0; + int32_t actual = ScreenClientWindowAdapter::GetInstance().MoveWindow(windowId, startX, startY); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_MOVE_WINDOW_ERROR, actual); +} + +/** + * @tc.name: MoveWindow_002 + * @tc.desc: Verify the MoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, MoveWindow_002, TestSize.Level1) +{ + int32_t windowId = 1; + int32_t startX = 0; + int32_t startY = 0; + int32_t actual = ScreenClientWindowAdapter::GetInstance().MoveWindow(windowId, startX, startY); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: RemoveWindow_001 + * @tc.desc: Verify the RemoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, RemoveWindow_001, TestSize.Level1) +{ + int32_t windowId = 0; + int32_t actual = ScreenClientWindowAdapter::GetInstance().RemoveWindow(windowId); + EXPECT_EQ(ERR_DH_SCREEN_SCREENCLIENT_REMOVE_WINDOW_ERROR, actual); +} + +/** + * @tc.name: RemoveWindow_002 + * @tc.desc: Verify the RemoveWindow function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenClientWindowAdapterTest, RemoveWindow_002, TestSize.Level1) +{ + int32_t windowId = 1; + int32_t actual = ScreenClientWindowAdapter::GetInstance().RemoveWindow(windowId); + EXPECT_EQ(DH_SUCCESS, actual); +} +} +} \ No newline at end of file diff --git a/services/screenservice/sinkservice/BUILD.gn b/services/screenservice/sinkservice/BUILD.gn new file mode 100644 index 00000000..806fc477 --- /dev/null +++ b/services/screenservice/sinkservice/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_sink") { + include_dirs = [ + "//third_party/json/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${windowmanager_path}/interfaces/innerkits/dm", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./dscreenservice/include", + "./screenregionmgr/include", + "${interfaces_path}/innerkits/native_cpp/screen_sink/include", + "${interfaces_path}/innerkits/native_cpp/screen_sink/include/callback", + "${interfaces_path}/innerkits/native_cpp/screen_source/include", + "${interfaces_path}/innerkits/native_cpp/screen_source/include/callback", + "${common_path}/include", + "${services_path}/common/utils/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/screenclient/include/", + ] + + sources = [ + "${services_path}/common/utils/src/dscreen_maprelation.cpp", + "${services_path}/common/utils/src/video_param.cpp", + "${interfaces_path}/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp", + "${interfaces_path}/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp", + "./dscreenservice/src/dscreen_sink_service.cpp", + "./dscreenservice/src/dscreen_sink_stub.cpp", + "./screenregionmgr/src/screenregion.cpp", + "./screenregionmgr/src/screenregionmgr.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${common_path}:distributed_screen_utils", + "${services_path}/screentransport/screensinktrans:distributed_screen_sinktrans", + "${services_path}/screenclient:distributed_screen_client", + "//foundation/graphic/standard/frameworks/surface:surface", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/dm:libdm", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensink\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_service.h b/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_service.h new file mode 100644 index 00000000..a314bacb --- /dev/null +++ b/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_service.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SINK_SERVICE_H +#define OHOS_DSCREEN_SINK_SERVICE_H + +#include "ipc_object_stub.h" +#include "system_ability.h" + +#include "dscreen_sink_stub.h" +#include "screenregionmgr.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSinkService : public SystemAbility, public DScreenSinkStub, + public std::enable_shared_from_this { +DECLARE_SYSTEM_ABILITY(DScreenSinkService); +public: + DScreenSinkService(int32_t saId, bool runOnCreate); + ~DScreenSinkService() = default; + int32_t InitSink(const std::string ¶ms) override; + int32_t ReleaseSink() override; + int32_t SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) override; + int32_t UnsubscribeLocalHardware(const std::string &dhId) override; + void DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) override; + +protected: + void OnStart() override; + void OnStop() override; + DISALLOW_COPY_AND_MOVE(DScreenSinkService); + +private: + std::shared_ptr screenRegionMgr_ = nullptr; + bool registerToService_ = false; + + bool Init(); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_stub.h b/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_stub.h new file mode 100644 index 00000000..68f8c47a --- /dev/null +++ b/services/screenservice/sinkservice/dscreenservice/include/dscreen_sink_stub.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SINK_STUB_H +#define OHOS_DSCREEN_SINK_STUB_H + +#include + +#include "iremote_stub.h" + +#include "idscreen_sink.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSinkStub : public IRemoteStub { +public: + DScreenSinkStub(); + virtual ~DScreenSinkStub(); + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +private: + using DScreenSinkFunc = int32_t (DScreenSinkStub::*)(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + std::map memberFuncMap_; + + int32_t InitSinkInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t ReleaseSinkInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t SubscribeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t UnsubscribeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t DScreenNotifyInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_service.cpp b/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_service.cpp new file mode 100644 index 00000000..643b4155 --- /dev/null +++ b/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_service.cpp @@ -0,0 +1,101 @@ +/* + * 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 "dscreen_sink_service.h" + +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +REGISTER_SYSTEM_ABILITY_BY_ID(DScreenSinkService, DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID, true); + +DScreenSinkService::DScreenSinkService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +{ + DHLOGI("DScreenSinkService construct."); +} + +void DScreenSinkService::OnStart() +{ + DHLOGI("dscreen sink service start."); + if (!Init()) { + DHLOGE("DScreenSinkService init failed."); + return; + } + DHLOGI("DScreenSinkService start success."); +} + +void DScreenSinkService::OnStop() +{ + DHLOGI("dscreen sink service stop."); + registerToService_ = false; +} + +bool DScreenSinkService::Init() +{ + DHLOGI("dscreen sink service start init."); + if (!registerToService_) { + bool ret = Publish(this); + if (!ret) { + DHLOGE("dscreen sink publish service failed."); + return false; + } + registerToService_ = true; + } + DHLOGI("dscreenService init success."); + return true; +} + +int32_t DScreenSinkService::InitSink(const std::string ¶ms) +{ + DHLOGI("InitSink"); + return DH_SUCCESS; +} + +int32_t DScreenSinkService::ReleaseSink() +{ + DHLOGI("ReleaseSink"); + return ScreenRegionManager::GetInstance().ReleaseAllRegions(); +} + +int32_t DScreenSinkService::SubscribeLocalHardware(const std::string &dhId, const std::string ¶m) +{ + DHLOGI("SubscribeLocalHardware"); + return DH_SUCCESS; +} + +int32_t DScreenSinkService::UnsubscribeLocalHardware(const std::string &dhId) +{ + DHLOGI("UnsubscribeLocalHardware"); + return DH_SUCCESS; +} + +void DScreenSinkService::DScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent) +{ + DHLOGI("DScreenNotify, devId:%s, eventCode: %d, eventContent:%s", GetAnonyString(devId).c_str(), + eventCode, eventContent.c_str()); + ScreenRegionManager::GetInstance().HandleDScreenNotify(devId, eventCode, eventContent); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_stub.cpp b/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_stub.cpp new file mode 100644 index 00000000..5ca32cd5 --- /dev/null +++ b/services/screenservice/sinkservice/dscreenservice/src/dscreen_sink_stub.cpp @@ -0,0 +1,111 @@ +/* + * 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 "dscreen_sink_stub.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +DScreenSinkStub::DScreenSinkStub() +{ + DHLOGI("DScreenSinkStub construct."); + memberFuncMap_[INIT_SINK] = &DScreenSinkStub::InitSinkInner; + memberFuncMap_[RELEASE_SINK] = &DScreenSinkStub::ReleaseSinkInner; + memberFuncMap_[SUBSCRIBE_DISTRIBUTED_HARDWARE] = &DScreenSinkStub::SubscribeDistributedHardwareInner; + memberFuncMap_[UNSUBSCRIBE_DISTRIBUTED_HARDWARE] = &DScreenSinkStub::UnsubscribeDistributedHardwareInner; + memberFuncMap_[DSCREEN_NOTIFY] = &DScreenSinkStub::DScreenNotifyInner; +} + +DScreenSinkStub::~DScreenSinkStub() +{ + DHLOGI("DScreenSinkStub deconstruct."); +} + +int32_t DScreenSinkStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("OnRemoteRequest, code: %d", code); + std::u16string desc = DScreenSinkStub::GetDescriptor(); + std::u16string remoteDesc = data.ReadInterfaceToken(); + if (desc != remoteDesc) { + DHLOGE("DScreenSinkStub::OnRemoteRequest remoteDesc is invalid!"); + return ERR_INVALID_DATA; + } + + const auto &iter = memberFuncMap_.find(code); + if (iter == memberFuncMap_.end()) { + DHLOGE("invalid request code."); + return ERR_DH_SCREEN_SA_INVALID_IPC_CALL; + } + DScreenSinkFunc &func = iter->second; + return (this->*func)(data, reply, option); +} + +int32_t DScreenSinkStub::InitSinkInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("InitSinkInner"); + std::string param = data.ReadString(); + int32_t ret = InitSink(param); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSinkStub::ReleaseSinkInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("ReleaseSinkInner"); + int32_t ret = ReleaseSink(); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSinkStub::SubscribeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("SubscribeDistributedHardwareInner"); + std::string dhId = data.ReadString(); + std::string param = data.ReadString(); + int32_t ret = SubscribeLocalHardware(dhId, param); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSinkStub::UnsubscribeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("UnsubscribeDistributedHardwareInner"); + std::string dhId = data.ReadString(); + int32_t ret = UnsubscribeLocalHardware(dhId); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSinkStub::DScreenNotifyInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DScreenNotifyInner"); + std::string devId = data.ReadString(); + int32_t eventCode = data.ReadInt32(); + std::string eventContent = data.ReadString(); + + DScreenNotify(devId, eventCode, eventContent); + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h b/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h new file mode 100644 index 00000000..8c400b67 --- /dev/null +++ b/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SCREEN_REGION_H +#define OHOS_DSCREEN_SCREEN_REGION_H + +#include "surface.h" + +#include "iscreen_sink_trans_callback.h" +#include "iscreen_sink_trans.h" +#include "dscreen_maprelation.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenSinkTransCallback : public IScreenSinkTransCallback { +public: + ~ScreenSinkTransCallback() override {}; + virtual void OnTransError(int32_t err, const std::string &content) = 0; + virtual void OnError(int32_t err, const std::string &content) override + { + OnTransError(err, content); + } +}; + +class ScreenRegion : public ScreenSinkTransCallback, public std::enable_shared_from_this { +public: + ScreenRegion(const std::string &remoteDevId, uint64_t screenId, uint64_t displayId); + ~ScreenRegion(); + void OnTransError(int32_t err, const std::string &content) override; + void SetVideoParam(std::shared_ptr &videoParam); + void SetMapRelation(std::shared_ptr &mapRElation); + std::string GetRemoteDevId(); + uint64_t GetScreenId(); + uint64_t GetDisplayId(); + int32_t SetUp(); + int32_t Start(); + int32_t Stop(); + +private: + std::string remoteDevId_; + uint64_t screenId_; // local screen id + uint64_t displayId_; // local display id + bool isRunning = false; + + std::shared_ptr videoParam_ = nullptr; + std::shared_ptr mapRelation_ = nullptr; + sptr surface_ = nullptr; + int32_t windowId_ = INVALID_WINDOW_ID; + std::shared_ptr sinkTrans_ = nullptr; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h b/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h new file mode 100644 index 00000000..65fcd09a --- /dev/null +++ b/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SCREEN_REGION_MGR_H +#define OHOS_DSCREEN_SCREEN_REGION_MGR_H + +#include +#include + +#include "single_instance.h" + +#include "screenregion.h" +#include "idscreen_source.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenRegionManager { +DECLARE_SINGLE_INSTANCE_BASE(ScreenRegionManager); +public: + int32_t ReleaseAllRegions(); + void HandleDScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent); + +private: + ScreenRegionManager(); + ~ScreenRegionManager(); + std::map> screenRegions_; + std::mutex screenRegionsMtx_; + + sptr GetDScreenSourceSA(const std::string &devId); + int32_t NotifyRemoteScreenService(const std::string &remoteDevId, const std::string &dhId, + int32_t eventCode, const std::string &eventContent); + void HandleNotifySetUp(const std::string &remoteDevId, const std::string &eventContent); + void NotifyRemoteSourceSetUpResult(const std::string &remoteDevId, const std::string &dhId, + int32_t errCode, const std::string &errContent); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp b/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp new file mode 100644 index 00000000..9fdf73b1 --- /dev/null +++ b/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp @@ -0,0 +1,175 @@ +/* + * 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 "screenregion.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" +#include "screen_client.h" +#include "screen_client_common.h" +#include "screen_sink_trans.h" + +namespace OHOS { +namespace DistributedHardware { +ScreenRegion::ScreenRegion(const std::string &remoteDevId, uint64_t screenId, uint64_t displayId) +{ + DHLOGD("ScreenRegion construct"); + remoteDevId_ = remoteDevId; + screenId_ = screenId; + displayId_ = displayId; + windowId_ = INVALID_WINDOW_ID; +} + +ScreenRegion::~ScreenRegion() +{ + DHLOGD("ScreenRegion deConstruct"); + if (!sinkTrans_) { + sinkTrans_->Release(); + } +} + +void ScreenRegion::OnTransError(int32_t err, const std::string &content) +{ + DHLOGE("OnTransError, err: %d", err); + Stop(); +} + +void ScreenRegion::SetVideoParam(std::shared_ptr &videoParam) +{ + videoParam_ = videoParam; +} + +void ScreenRegion::SetMapRelation(std::shared_ptr &mapRelation) +{ + mapRelation_ = mapRelation; +} + +uint64_t ScreenRegion::GetScreenId() +{ + return screenId_; +} + +uint64_t ScreenRegion::GetDisplayId() +{ + return displayId_; +} + +std::string ScreenRegion::GetRemoteDevId() +{ + return remoteDevId_; +} + +int32_t ScreenRegion::SetUp() +{ + DHLOGI("ScreenRegion::SetUp, remoteDevId: %s", GetAnonyString(remoteDevId_).c_str()); + + std::shared_ptr windowProperty = std::make_shared(); + windowProperty->displayId = displayId_; + + ScreenRect screenRect = mapRelation_->GetScreenRect(); + windowProperty->startX = screenRect.startX; + windowProperty->startY = screenRect.startY; + windowProperty->width = screenRect.width; + windowProperty->height = screenRect.height; + + windowId_ = ScreenClient::GetInstance().AddWindow(windowProperty); + if (windowId_ < 0) { + DHLOGE("AddWindow failed."); + return ERR_DH_SCREEN_SA_DSCREEN_SCREENGION_SETUP_FAILED; + } + int32_t ret = ScreenClient::GetInstance().ShowWindow(windowId_); + if (ret != DH_SUCCESS) { + DHLOGE("show window failed."); + return ERR_DH_SCREEN_SA_DSCREEN_SCREENGION_SETUP_FAILED; + } + + sptr surface = ScreenClient::GetInstance().GetSurface(windowId_); + if (!surface) { + DHLOGE("get window surface failed."); + return ERR_DH_SCREEN_SA_DSCREEN_SCREENGION_SETUP_FAILED; + } + + surface_ = surface; + + if (!sinkTrans_) { + sinkTrans_ = std::make_shared(); + } + + sinkTrans_->RegisterStateCallback(shared_from_this()); + sinkTrans_->SetImageSurface(surface_); + ret = sinkTrans_->SetUp(*videoParam_, *videoParam_, remoteDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("sinkTrans setup failed."); + return ERR_DH_SCREEN_SA_DSCREEN_SCREENGION_SETUP_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ScreenRegion::Start() +{ + DHLOGI("ScreenRegion::Start remoteDevId: %s", GetAnonyString(remoteDevId_).c_str()); + if (!sinkTrans_) { + DHLOGE("sink trans not init."); + return ERR_DH_SCREEN_SA_SINKTRANS_NOT_INIT; + } + + int32_t ret = sinkTrans_->Start(); + if (ret != DH_SUCCESS) { + DHLOGE("sink trans start failed."); + return ret; + } + isRunning = true; + return DH_SUCCESS; +} + +int32_t ScreenRegion::Stop() +{ + DHLOGI("ScreenRegion::Stop remoteDevId: %s", GetAnonyString(remoteDevId_).c_str()); + if (!isRunning) { + DHLOGI("ScreenRegion not running, no need stop"); + return DH_SUCCESS; + } + + if (!sinkTrans_) { + DHLOGE("sink trans not init."); + return ERR_DH_SCREEN_SA_SINKTRANS_NOT_INIT; + } + + int32_t ret = sinkTrans_->Stop(); + if (ret != DH_SUCCESS) { + DHLOGE("sink trans stop failed."); + return ret; + } + + ret = sinkTrans_->Release(); + if (ret != DH_SUCCESS) { + DHLOGE("sink trans release failed."); + return ret; + } + + ret = ScreenClient::GetInstance().RemoveWindow(windowId_); + if (ret != DH_SUCCESS) { + DHLOGE("remove window failed."); + return ret; + } + + isRunning = false; + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp b/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp new file mode 100644 index 00000000..48457eeb --- /dev/null +++ b/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp @@ -0,0 +1,199 @@ +/* + * 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 "screenregionmgr.h" + +#include "display_manager.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "nlohmann/json.hpp" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_maprelation.h" +#include "dscreen_util.h" +#include "idscreen_source.h" +#include "screen_client.h" +#include "screen_client_common.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(ScreenRegionManager); +ScreenRegionManager::ScreenRegionManager() +{ + DHLOGI("ScreenRegionManager"); +} + +ScreenRegionManager::~ScreenRegionManager() +{ + DHLOGI("~ScreenRegionManager"); +} + +int32_t ScreenRegionManager::ReleaseAllRegions() +{ + DHLOGI("ScreenRegionManager::ReleaseAllRegion"); + std::lock_guard lock(screenRegionsMtx_); + for (const auto &item : screenRegions_) { + std::shared_ptr screenRegion = item.second; + if (!screenRegion) { + continue; + } + int32_t ret = screenRegion->Stop(); + if (ret != DH_SUCCESS) { + DHLOGE("Release region failed, remoteDevId: %s, err: %d", + GetAnonyString(screenRegion->GetRemoteDevId()).c_str(), ret); + } + } + screenRegions_.clear(); + return DH_SUCCESS; +} + +void ScreenRegionManager::HandleDScreenNotify(const std::string &remoteDevId, int32_t eventCode, + const std::string &eventContent) +{ + DHLOGI("HandleDScreenNotify, remoteDevId: %s, eventCode: %d", GetAnonyString(remoteDevId).c_str(), eventCode); + if (eventCode == NOTIFY_SINK_SETUP) { + HandleNotifySetUp(remoteDevId, eventContent); + return; + } + DHLOGE("invalid event."); +} + +void ScreenRegionManager::HandleNotifySetUp(const std::string &remoteDevId, const std::string &eventContent) +{ + DHLOGI("HandleNotifySetUp, remoteDevId: %s", GetAnonyString(remoteDevId).c_str()); + json eventContentJson = json::parse(eventContent, nullptr, false); + if (eventContentJson.is_discarded()) { + DHLOGE("HandleNotifySetUp, eventJsonContent is invalid."); + NotifyRemoteSourceSetUpResult(remoteDevId, "", ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL, ""); + return; + } + + if (!eventContentJson.contains(KEY_SCREEN_ID) || !eventContentJson.contains(KEY_DH_ID) || + !eventContentJson.contains(KEY_VIDEO_PARAM) || !eventContentJson.contains(KEY_MAPRELATION)) { + DHLOGE("HandleNotifySetUp, eventJsonContent is invalid."); + NotifyRemoteSourceSetUpResult(remoteDevId, "", ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL, ""); + return; + } + + uint64_t screenId = eventContentJson[KEY_SCREEN_ID]; + std::string dhId = eventContentJson[KEY_DH_ID]; + std::shared_ptr videoParam = + std::make_shared(eventContentJson[KEY_VIDEO_PARAM].get()); + std::shared_ptr mapRelation = + std::make_shared(eventContentJson[KEY_MAPRELATION].get()); + + uint64_t displayId = Rosen::DisplayManager::GetInstance().GetDefaultDisplayId(); + std::shared_ptr screenRegion = std::make_shared(remoteDevId, screenId, displayId); + screenRegion->SetVideoParam(videoParam); + screenRegion->SetMapRelation(mapRelation); + + int32_t ret = DH_SUCCESS; + { + std::lock_guard lock(screenRegionsMtx_); + if (screenRegions_.count(remoteDevId) != 0) { + ret = screenRegions_[remoteDevId]->Stop(); + } + + if (ret != DH_SUCCESS) { + DHLOGE("screenRegion stop failed, remoteDevId: %s, err: %d", + GetAnonyString(screenRegions_[remoteDevId]->GetRemoteDevId()).c_str(), ret); + NotifyRemoteSourceSetUpResult(remoteDevId, dhId, ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL, ""); + return; + } + screenRegions_[remoteDevId] = screenRegion; + } + + ret = screenRegion->SetUp(); + if (ret != DH_SUCCESS) { + DHLOGE("screen region start failed"); + NotifyRemoteSourceSetUpResult(remoteDevId, dhId, ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL, ""); + return; + } + + ret = screenRegion->Start(); + if (ret != DH_SUCCESS) { + DHLOGE("screen region start failed"); + NotifyRemoteSourceSetUpResult(remoteDevId, dhId, ERR_DH_SCREEN_SA_SCREENREGION_START_FAIL, ""); + return; + } + + NotifyRemoteSourceSetUpResult(remoteDevId, dhId, DH_SUCCESS, ""); +} + +void ScreenRegionManager::NotifyRemoteSourceSetUpResult(const std::string &remoteDevId, const std::string &dhId, + int32_t errCode, const std::string &errContent) +{ + DHLOGI("NotifyRemoteSourceSetUpResult, sourceDevId: %s, dhId: %s, errCode: %d", + GetAnonyString(remoteDevId).c_str(), GetAnonyString(dhId).c_str(), errCode); + int32_t eventCode = NOTIFY_SOURCE_SETUP_RESULT; + + json eventContentJson; + eventContentJson[KEY_DH_ID] = dhId; + eventContentJson[KEY_ERR_CODE] = errCode; + eventContentJson[KEY_ERR_CONTENT] = errContent; + + std::string eventContent = eventContentJson.dump(); + + NotifyRemoteScreenService(remoteDevId, dhId, eventCode, eventContent); +} + +int32_t ScreenRegionManager::NotifyRemoteScreenService(const std::string &remoteDevId, const std::string &dhId, + int32_t eventCode, const std::string &eventContent) +{ + DHLOGI("Notify remote source screen service, remote devId: %s, eventCode: %d", + GetAnonyString(remoteDevId).c_str(), eventCode); + sptr remoteSourceSA = GetDScreenSourceSA(remoteDevId); + if (!remoteSourceSA) { + DHLOGE("get remote source sa failed."); + return ERR_DH_SCREEN_SA_GET_REMOTE_SOURCE_SERVICE_FAIL; + } + std::string localDevId; + int32_t ret = GetLocalDeviceNetworkId(localDevId); + if (ret != DH_SUCCESS) { + DHLOGE("notify remote screen service failed, cannot get local device id"); + return ret; + } + remoteSourceSA->DScreenNotify(localDevId, eventCode, eventContent); + return DH_SUCCESS; +} + +sptr ScreenRegionManager::GetDScreenSourceSA(const std::string &devId) +{ + DHLOGI("GetDScreenSourceSA, devId: %s", GetAnonyString(devId).c_str()); + sptr samgr = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + DHLOGE("Failed to get system ability mgr."); + return nullptr; + } + auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, devId); + if (remoteObject == nullptr) { + DHLOGE("remoteObject is null"); + return nullptr; + } + + sptr remoteSourceSA = iface_cast(remoteObject); + if (remoteSourceSA == nullptr) { + DHLOGE("Failed to get remote dscreen source sa"); + return nullptr; + } + return remoteSourceSA; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/BUILD.gn b/services/screenservice/sourceservice/BUILD.gn new file mode 100644 index 00000000..37777849 --- /dev/null +++ b/services/screenservice/sourceservice/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_source") { + include_dirs = [ + "//third_party/json/include", + "${windowmanager_path}/interfaces/innerkits/dm", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./dscreenservice/include", + "./dscreenservice/include/callback", + "./dscreenmgr/include", + "${interfaces_path}/innerkits/native_cpp/screen_sink/include", + "${interfaces_path}/innerkits/native_cpp/screen_sink/include/callback", + "${interfaces_path}/innerkits/native_cpp/screen_source/include", + "${interfaces_path}/innerkits/native_cpp/screen_source/include/callback", + "${common_path}/include", + "${services_path}/common/utils/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/screentransport/screensourcetrans/include", + ] + + sources = [ + "${services_path}/common/utils/src/dscreen_maprelation.cpp", + "${services_path}/common/utils/src/video_param.cpp", + "${interfaces_path}/innerkits/native_cpp/screen_sink/src/dscreen_sink_proxy.cpp", + "${interfaces_path}/innerkits/native_cpp/screen_source/src/dscreen_source_proxy.cpp", + "./dscreenservice/src/callback/dscreen_source_callback_proxy.cpp", + "./dscreenservice/src/dscreen_source_service.cpp", + "./dscreenservice/src/dscreen_source_stub.cpp", + "./dscreenmgr/src/dscreen.cpp", + "./dscreenmgr/src/dscreen_manager.cpp", + "./dscreenmgr/src/screen_manager_adapter.cpp", + ] + + deps = [ + "//utils/native/base:utils", + "${common_path}:distributed_screen_utils", + "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "//foundation/graphic/standard/frameworks/surface:surface", + "${windowmanager_path}/interfaces/innerkits:wm_interface", + "${windowmanager_path}/dm:libdm", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensource\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h b/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h new file mode 100644 index 00000000..961ef1e3 --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_H +#define OHOS_DSCREEN_H + +#include +#include +#include +#include + +#include "dscreen_constants.h" +#include "iscreen_source_trans.h" +#include "iscreen_source_trans_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreen; +class IDScreenCallback { +public: + virtual ~IDScreenCallback() {}; + virtual void OnRegResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) = 0; + virtual void OnUnregResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) = 0; +}; + +class ScreenSourceTransCallback : public IScreenSourceTransCallback { +public: + ~ScreenSourceTransCallback() override {}; + virtual void OnTransError(int32_t err, const std::string &content) = 0; + virtual void OnError(int32_t err, const std::string &content) override + { + OnTransError(err, content); + } +}; + +class Task { +public: + Task(TaskType taskType, const std::string &taskId, const std::string &taskParam) : taskType_(taskType), + taskId_(taskId), taskParam_(taskParam) {}; + Task(TaskType taskType, const std::string &taskParam) : taskType_(taskType), + taskId_(""), taskParam_(taskParam) {}; + ~Task() {}; + + TaskType GetTaskType() + { + return taskType_; + }; + std::string GetTaskId() + { + return taskId_; + }; + std::string GetTaskParam() + { + return taskParam_; + }; + +private: + TaskType taskType_; + std::string taskId_; + std::string taskParam_; +}; + +class DScreen : public ScreenSourceTransCallback, public std::enable_shared_from_this { +public: + ~DScreen(); + DScreen(const std::string &devId, const std::string &dhId, std::shared_ptr dscreenCallback); + void OnTransError(int32_t err, const std::string &content) override; + + void SetVideoParam(std::shared_ptr &videoParam); + std::shared_ptr GetVideoParam(); + void SetState(DScreenState state); + DScreenState GetState() const; + uint64_t GetScreenId() const; + std::string GetDHId() const; + std::string GetDevId() const; + int32_t AddTask(const std::shared_ptr &task); + +private: + void TaskThreadLoop(); + void HandleTask(const std::shared_ptr &task); + void HandleEnable(const std::string ¶m, const std::string &taskId); + void HandleDisable(const std::string &taskId); + void HandleConnect(); + void HandleDisconnect(); + int32_t SetUp(); + int32_t Start(); + int32_t Stop(); + + static constexpr uint8_t TASK_WAIT_SECONDS = 1; + + std::string devId_; + std::string dhId_; + uint64_t screenId_ = SCREEN_ID_INVALID; + std::shared_ptr videoParam_ = nullptr; + std::shared_ptr sourceTrans_ = nullptr; + std::shared_ptr dscreenCallback_ = nullptr; + + DScreenState curState_; + std::mutex stateMtx_; + std::thread taskQueueThread_; + std::condition_variable taskQueueCond_; + std::mutex taskQueueMtx_; + std::queue> taskQueue_; + bool taskThreadRunning_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h b/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h new file mode 100644 index 00000000..a32ec75c --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_MGR_H +#define OHOS_DSCREEN_MGR_H + +#include "dm_common.h" +#include "single_instance.h" +#include "screen_manager.h" + +#include "dscreen.h" +#include "dscreen_maprelation.h" +#include "idscreen_sink.h" +#include "idscreen_source_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenCallback : public IDScreenCallback { +public: + void OnRegResult(const std::shared_ptr &dScreen, const std::string &reqId, + int32_t status, const std::string &data) override; + void OnUnregResult(const std::shared_ptr &dScreen, const std::string &reqId, + int32_t status, const std::string &data) override; +}; + +class DScreenManager : public Rosen::ScreenManager::IScreenGroupListener, + public std::enable_shared_from_this { +DECLARE_SINGLE_INSTANCE_BASE(DScreenManager); +public: + void OnChange(const std::vector &screenIds, Rosen::ScreenGroupChangeEvent event) override; + + void OnRegResult(const std::shared_ptr &dScreen, const std::string &reqId, + int32_t status, const std::string &data); + void OnUnregResult(const std::shared_ptr &dScreen, const std::string &reqId, + int32_t status, const std::string &data); + + int32_t Init(); + int32_t UnInit(); + int32_t EnableDistributedScreen(const std::string &devId, const std::string &dhId, const std::string ¶m, + const std::string &reqId); + int32_t DisableDistributedScreen(const std::string &devId, const std::string &dhId, const std::string &reqId); + void HandleDScreenNotify(const std::string &devId, int32_t eventCode, const std::string &eventContent); + void RegisterDScreenCallback(const sptr &callback); + +private: + ~DScreenManager(); + DScreenManager(); + std::mutex dScreenMapMtx_; + std::mutex dScreenMapRelationMtx_; + std::map> mapRelations_; + std::map> dScreens_; + sptr dScreenSourceCallbackProxy_ = nullptr; + std::shared_ptr dScreenCallback_ = nullptr; + + void HandleScreenChange(const std::shared_ptr &changedScreen, Rosen::ScreenGroupChangeEvent event); + std::shared_ptr FindDScreenByScreenId(uint64_t screenId); + sptr GetDScreenSinkSA(const std::string &devId); + int32_t NotifyRemoteScreenService(const std::string &devId, int32_t eventCode, const std::string &eventContent); + void NotifyRemoteSinkSetUp(const std::shared_ptr &dScreen); + void HandleNotifySetUpResult(const std::string &remoteDevId, const std::string &eventContent); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/include/screen_manager_adapter.h b/services/screenservice/sourceservice/dscreenmgr/include/screen_manager_adapter.h new file mode 100644 index 00000000..836c4edd --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/include/screen_manager_adapter.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_MGR_ADAPTER_H +#define OHOS_SCREEN_MGR_ADAPTER_H + +#include + +#include "single_instance.h" +#include "screen_manager.h" + +#include "dscreen_maprelation.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenMgrAdapter { +DECLARE_SINGLE_INSTANCE_BASE(ScreenMgrAdapter); + +public: + uint64_t CreateVirtualScreen(const std::string &devId, const std::string &dhId, + const std::shared_ptr &videoParam); + int32_t RegisterScreenGroupListener(sptr listener); + int32_t UnregisterScreenGroupListener(sptr listener); + int32_t RemoveVirtualScreen(uint64_t screenId); + int32_t SetImageSurface(uint64_t screenId, sptr surface); + std::shared_ptr GetMapRelation(uint64_t screenId); + void RemoveScreenFromGroup(uint64_t screenId); + +private: + ScreenMgrAdapter() = default; + ~ScreenMgrAdapter(); + + bool listenerRegistered = false; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp new file mode 100644 index 00000000..22bf467c --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp @@ -0,0 +1,349 @@ +/* + * 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 "dscreen.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" +#include "screen_manager_adapter.h" +#include "screen_source_trans.h" + +namespace OHOS { +namespace DistributedHardware { +DScreen::DScreen(const std::string &devId, const std::string &dhId, + std::shared_ptr dscreenCallback) +{ + DHLOGD("DScreen construct, devId: %s, dhId: %s", GetAnonyString(devId).c_str(), + GetAnonyString(dhId).c_str()); + devId_ = devId; + dhId_ = dhId; + dscreenCallback_ = dscreenCallback; + SetState(DISABLED); + taskThreadRunning_ = true; + taskQueueThread_ = std::thread(&DScreen::TaskThreadLoop, this); +} + +DScreen::~DScreen() +{ + DHLOGD("DScreen deconstruct, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + taskThreadRunning_ = false; + taskQueueCond_.notify_all(); + if (taskQueueThread_.joinable()) { + taskQueueThread_.join(); + } + int32_t ret = DH_SUCCESS; + if (sourceTrans_) { + ret = sourceTrans_->Release(); + } + if (ret != DH_SUCCESS) { + DHLOGE("source trans release failed. ret: %d", ret); + } + + if (screenId_ != SCREEN_ID_INVALID) { + ret = ScreenMgrAdapter::GetInstance().RemoveVirtualScreen(screenId_); + } + + if (ret != DH_SUCCESS) { + DHLOGE("remove virtual screen failed."); + } + videoParam_ = nullptr; + sourceTrans_ = nullptr; + DHLOGD("DScreen deconstruct end."); +} + +void DScreen::OnTransError(int32_t err, const std::string &content) +{ + DHLOGD("OnTransError, err: %d", err); + AddTask(std::make_shared(TaskType::TASK_DISCONNECT, "")); + ScreenMgrAdapter::GetInstance().RemoveScreenFromGroup(screenId_); +} + +void DScreen::SetVideoParam(std::shared_ptr &videoParam) +{ + videoParam_ = videoParam; +} + +std::shared_ptr DScreen::GetVideoParam() +{ + return videoParam_; +} + +void DScreen::SetState(DScreenState state) +{ + std::lock_guard lock(stateMtx_); + curState_ = state; +} + +DScreenState DScreen::GetState() const +{ + return curState_; +} + +uint64_t DScreen::GetScreenId() const +{ + return screenId_; +} + +std::string DScreen::GetDHId() const +{ + return dhId_; +} + +std::string DScreen::GetDevId() const +{ + return devId_; +} + +int32_t DScreen::AddTask(const std::shared_ptr &task) +{ + DHLOGI("DScreen::AddTask, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (!task) { + DHLOGE("AddTask, task is invalid."); + return ERR_DH_SCREEN_SA_DSCREEN_TASK_NOT_VALID; + } + DHLOGI("AddTask, task type: %d", task->GetTaskType()); + { + std::lock_guard lock(taskQueueMtx_); + taskQueue_.push(task); + } + taskQueueCond_.notify_all(); + return DH_SUCCESS; +} + +void DScreen::TaskThreadLoop() +{ + DHLOGI("DScreen taskThread start. devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + while (taskThreadRunning_) { + std::shared_ptr task; + { + std::unique_lock lock(taskQueueMtx_); + taskQueueCond_.wait_for(lock, std::chrono::seconds(TASK_WAIT_SECONDS), + [this]() { return !taskQueue_.empty(); }); + if (taskQueue_.empty()) { + continue; + } + task = taskQueue_.front(); + taskQueue_.pop(); + } + + if (task == nullptr) { + DHLOGD("task is null."); + continue; + } + + DHLOGD("run task, task queue size: %zu", taskQueue_.size()); + HandleTask(task); + } +} + +void DScreen::HandleTask(const std::shared_ptr &task) +{ + int32_t taskType = task->GetTaskType(); + DHLOGI("HandleTask, devId: %s, dhId: %s, task type: %d", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str(), taskType); + switch (taskType) { + case TaskType::TASK_ENABLE: + HandleEnable(task->GetTaskParam(), task->GetTaskId()); + break; + case TaskType::TASK_DISABLE: + HandleDisable(task->GetTaskId()); + break; + case TaskType::TASK_CONNECT: + HandleConnect(); + break; + case TaskType::TASK_DISCONNECT: + HandleDisconnect(); + break; + default: + DHLOGD("task type unkown."); + } +} + +void DScreen::HandleEnable(const std::string ¶m, const std::string &taskId) +{ + DHLOGI("HandleEnable, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + if (curState_ == ENABLED || curState_ == ENABLING || + curState_ == CONNECTING || curState_ == CONNECTED) { + dscreenCallback_->OnRegResult(shared_from_this(), taskId, DH_SUCCESS, ""); + return; + } + + SetState(ENABLING); + if (!videoParam_) { + videoParam_ = std::make_shared(); + } + + json attrJson = json::parse(param, nullptr, false); + if (attrJson.is_discarded()) { + DHLOGE("enable param json is invalid."); + dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED, + "enable param json is invalid."); + return; + } + + if (!attrJson.contains(KEY_SCREEN_WIDTH) || + !attrJson.contains(KEY_SCREEN_HEIGHT) || + !attrJson.contains(KEY_CODECTYPE)) { + DHLOGE("enable param is invalid."); + dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED, + "enable param is invalid."); + return; + } + + videoParam_->SetScreenWidth(attrJson[KEY_SCREEN_WIDTH]); + videoParam_->SetScreenHeight(attrJson[KEY_SCREEN_HEIGHT]); + std::string codecTypeStr = attrJson[KEY_CODECTYPE]; + videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_NV21); + videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_H264); + + uint64_t screenId = ScreenMgrAdapter::GetInstance().CreateVirtualScreen(devId_, dhId_, videoParam_); + if (screenId == SCREEN_ID_INVALID) { + DHLOGE("create virtual screen failed."); + dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED, + "create virtual screen failed."); + } + screenId_ = screenId; + SetState(ENABLED); + dscreenCallback_->OnRegResult(shared_from_this(), taskId, DH_SUCCESS, ""); +} + +void DScreen::HandleDisable(const std::string &taskId) +{ + DHLOGI("HandleDisable, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str()); + SetState(DISABLING); + Stop(); + int32_t ret = ScreenMgrAdapter::GetInstance().RemoveVirtualScreen(screenId_); + if (ret != DH_SUCCESS) { + DHLOGE("remove virtual screen failed."); + dscreenCallback_->OnUnregResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_DISABLE_FAILED, + "remove virtual screen failed."); + return; + } + SetState(DISABLED); + dscreenCallback_->OnUnregResult(shared_from_this(), taskId, DH_SUCCESS, ""); +} + +void DScreen::HandleConnect() +{ + DHLOGI("HandleConnect, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + + int32_t ret = SetUp(); + if (ret != DH_SUCCESS) { + SetState(ENABLED); + ScreenMgrAdapter::GetInstance().RemoveScreenFromGroup(screenId_); + DHLOGE("dScreen SetUp failed."); + return; + } + + ret = Start(); + if (ret != DH_SUCCESS) { + SetState(ENABLED); + ScreenMgrAdapter::GetInstance().RemoveScreenFromGroup(screenId_); + DHLOGE("dScreen Start failed."); + return; + } + SetState(CONNECTED); +} + +void DScreen::HandleDisconnect() +{ + DHLOGD("HandleDisconnect, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (curState_ != CONNECTED) { + DHLOGE("dscreen is not connected, cannot disconnect"); + return; + } + SetState(DISCONNECTING); + int32_t ret = Stop(); + if (ret != DH_SUCCESS) { + SetState(CONNECTED); + DHLOGE("dScreen Stop failed."); + return; + } + SetState(ENABLED); +} + +int32_t DScreen::SetUp() +{ + DHLOGD("SetUp, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + + if (!sourceTrans_) { + sourceTrans_ = std::make_shared(); + } + + sourceTrans_->RegisterStateCallback(shared_from_this()); + int32_t ret = sourceTrans_->SetUp(*videoParam_, *videoParam_, devId_); + if (ret != DH_SUCCESS) { + DHLOGE("source trans SetUp failed."); + return ret; + } + + sptr surface = sourceTrans_->GetImageSurface(); + + ScreenMgrAdapter::GetInstance().SetImageSurface(screenId_, surface); + DHLOGI("DScreen SetUp success."); + return DH_SUCCESS; +} + +int32_t DScreen::Start() +{ + DHLOGD("Start, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (!sourceTrans_) { + DHLOGE("source trans not init."); + return ERR_DH_SCREEN_SA_SOURCETRANS_NOT_INIT; + } + + int32_t ret = sourceTrans_->Start(); + if (ret != DH_SUCCESS) { + DHLOGE("source trans start failed."); + return ret; + } + return DH_SUCCESS; +} + +int32_t DScreen::Stop() +{ + DHLOGD("Stop, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), + GetAnonyString(dhId_).c_str()); + if (!sourceTrans_) { + DHLOGE("source trans not init."); + return ERR_DH_SCREEN_SA_SOURCETRANS_NOT_INIT; + } + + int32_t ret = sourceTrans_->Stop(); + if (ret != DH_SUCCESS) { + DHLOGE("source trans stop failed."); + return ret; + } + + ret = sourceTrans_->Release(); + if (ret != DH_SUCCESS) { + DHLOGE("source trans release failed."); + return ret; + } + + sourceTrans_ = nullptr; + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp b/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp new file mode 100644 index 00000000..6d7c308b --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp @@ -0,0 +1,400 @@ +/* + * 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 "dscreen_manager.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "nlohmann/json.hpp" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" +#include "idscreen_sink.h" +#include "screen_manager_adapter.h" + +using json = nlohmann::json; + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(DScreenManager); +DScreenManager::DScreenManager() +{ + DHLOGI("DScreenMgr construct."); +} + +DScreenManager::~DScreenManager() +{ + DHLOGI("DScreenMgr deConstruct."); +} + +int32_t DScreenManager::Init() +{ + DHLOGI("DScreenManager::Init"); + int32_t ret = ScreenMgrAdapter::GetInstance().RegisterScreenGroupListener(this); + if (ret != DH_SUCCESS) { + DHLOGE("DScreenManager Init failed, err: %d", ret); + } + if (!dScreenCallback_) { + dScreenCallback_ = std::make_shared(); + } + return ret; +} + +int32_t DScreenManager::UnInit() +{ + DHLOGI("DScreenManager::UnInit"); + int32_t ret = ScreenMgrAdapter::GetInstance().UnregisterScreenGroupListener(this); + if (ret != DH_SUCCESS) { + DHLOGE("DScreenManager UnInit failed, err: %d", ret); + } + dScreenCallback_ = nullptr; + + { + std::lock_guard lock(dScreenMapMtx_); + dScreens_.clear(); + } + + { + std::lock_guard lock(dScreenMapRelationMtx_); + mapRelations_.clear(); + } + DHLOGI("DScreenManager::UnInit success"); + return ret; +} + +void DScreenManager::OnChange(const std::vector &screenIds, Rosen::ScreenGroupChangeEvent event) +{ + DHLOGI("On Screen change, screenIds size: %d", screenIds.size()); + for (uint64_t screenId : screenIds) { + std::shared_ptr changedScreen = nullptr; + changedScreen = FindDScreenByScreenId(screenId); + if (!changedScreen) { + DHLOGD("screen change not about remote screen, screenId: %ulld", screenId); + continue; + } + HandleScreenChange(changedScreen, event); + } +} + +void DScreenManager::HandleScreenChange(const std::shared_ptr &changedScreen, + Rosen::ScreenGroupChangeEvent event) +{ + if (!changedScreen) { + DHLOGE("DScreenManager::HandleScreenChange, dScreen is null."); + return; + } + uint64_t screenId = changedScreen->GetScreenId(); + DHLOGI("DScreenManager::HandleScreenChange, screenId: %ulld, changeEvent: %", screenId, event); + if (event == Rosen::ScreenGroupChangeEvent::ADD_TO_GROUP) { + if (changedScreen->GetState() == CONNECTING) { + DHLOGD("screen is connecting, no need handle change"); + return; + } + std::shared_ptr mapRelation = + ScreenMgrAdapter::GetInstance().GetMapRelation(screenId); + if (!mapRelation) { + DHLOGE("mapRelation construct failed. screenId: %ulld", screenId); + return; + } + + std::shared_ptr videoParam = changedScreen->GetVideoParam(); + DisplayRect displayRect = mapRelation->GetDisplayRect(); + videoParam->SetVideoWidth(displayRect.width); + videoParam->SetVideoHeight(displayRect.height); + changedScreen->SetState(CONNECTING); + + { + std::lock_guard lock(dScreenMapRelationMtx_); + mapRelations_[screenId] = mapRelation; + } + NotifyRemoteSinkSetUp(changedScreen); + } else if (event == Rosen::ScreenGroupChangeEvent::REMOVE_FROM_GROUP) { + if (changedScreen->GetState() == DISCONNECTING) { + DHLOGD("screen is disconnecting, no need handle change"); + return; + } + std::shared_ptr mapRelation = nullptr; + { + std::lock_guard lock(dScreenMapRelationMtx_); + if (mapRelations_.count(screenId) == 0) { + DHLOGE("destroyed relation not found."); + return; + } + mapRelation = mapRelations_[screenId]; + mapRelations_.erase(screenId); + } + changedScreen->AddTask(std::make_shared(TaskType::TASK_DISCONNECT, "")); + } else if (event == Rosen::ScreenGroupChangeEvent::CHANGE_GROUP) { + DHLOGE("CHANGE_GROUP not implement."); + } else { + DHLOGE("unknown change type."); + } +} + +void DScreenCallback::OnRegResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGI("DScreenCallback::OnRegResult, devId: %s, dhId: %s, reqId: %s", + GetAnonyString(dScreen->GetDevId()).c_str(), GetAnonyString(dScreen->GetDHId()).c_str(), reqId.c_str()); + DScreenManager::GetInstance().OnRegResult(dScreen, reqId, status, data); +} + +void DScreenCallback::OnUnregResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGI("DScreenCallback::OnUnregResult, devId: %s, dhId: %s, reqId: %s", + GetAnonyString(dScreen->GetDevId()).c_str(), GetAnonyString(dScreen->GetDHId()).c_str(), reqId.c_str()); + DScreenManager::GetInstance().OnUnregResult(dScreen, reqId, status, data); +} + +void DScreenManager::OnRegResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGI("DScreenManager::OnRegResult, devId: %s, dhId: %s, reqId: %s", + GetAnonyString(dScreen->GetDevId()).c_str(), GetAnonyString(dScreen->GetDHId()).c_str(), reqId.c_str()); + if (!dScreenSourceCallbackProxy_) { + DHLOGE("dScreenSourceCallbackProxy is null"); + return; + } + dScreenSourceCallbackProxy_->OnNotifyRegResult(dScreen->GetDevId(), dScreen->GetDHId(), reqId, status, data); +} + +void DScreenManager::OnUnregResult(const std::shared_ptr &dScreen, + const std::string &reqId, int32_t status, const std::string &data) +{ + DHLOGI("DScreenManager::OnUnregResult, devId: %s, dhId: %s, reqId: %s", + GetAnonyString(dScreen->GetDevId()).c_str(), GetAnonyString(dScreen->GetDHId()).c_str(), reqId.c_str()); + if (!dScreenSourceCallbackProxy_) { + DHLOGE("dScreenSourceCallbackProxy is null"); + return; + } + dScreenSourceCallbackProxy_->OnNotifyUnregResult(dScreen->GetDevId(), dScreen->GetDHId(), reqId, status, data); +} + +int32_t DScreenManager::EnableDistributedScreen(const std::string &devId, const std::string &dhId, + const std::string &attrs, const std::string &reqId) +{ + DHLOGI("EnableDistributedScreen, devId: %s, dhId:%s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + std::string dScreenIdx = devId + SEPERATOR + dhId; + std::shared_ptr dScreen = nullptr; + if (dScreens_.count(dScreenIdx) != 0) { + dScreen = dScreens_[dScreenIdx]; + } + + if (dScreen == nullptr) { + dScreen = std::make_shared(devId, dhId, dScreenCallback_); + } + + int32_t dScreenState = dScreen->GetState(); + if (dScreenState != DISABLED && dScreenState != DISABLING) { + DHLOGE("dScreen state is invalid."); + return ERR_DH_SCREEN_SA_ENABLE_FAILED; + } + + dScreens_[dScreenIdx] = dScreen; + int32_t ret = dScreen->AddTask(std::make_shared(TaskType::TASK_ENABLE, reqId, attrs)); + if (ret != DH_SUCCESS) { + DHLOGE("EnableDistributedScreen, add task failed. devId: %s, dhId:%s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + } + return ret; +} + +int32_t DScreenManager::DisableDistributedScreen(const std::string &devId, const std::string &dhId, + const std::string &reqId) +{ + DHLOGI("DisableDistributedScreen, devId: %s, dhId:%s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + + std::string dScreenIdx = devId + SEPERATOR + dhId; + if (dScreens_.count(dScreenIdx) == 0) { + DHLOGE("dscreen not found, devId: %s, dhId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str()); + return ERR_DH_SCREEN_SA_DISABLE_FAILED; + } + + int32_t dScreenState = dScreens_[dScreenIdx]->GetState(); + int32_t ret = DH_SUCCESS; + switch (dScreenState) { + case DISABLED: + case DISABLING: + DHLOGE("dScreen state is invalid."); + ret = ERR_DH_SCREEN_SA_DISABLE_FAILED; + break; + case ENABLED: + case ENABLING: + ret = dScreens_[dScreenIdx]->AddTask(std::make_shared(TaskType::TASK_DISABLE, reqId, "")); + break; + case CONNECTING: + case CONNECTED: + case DISCONNECTING: + ret = dScreens_[dScreenIdx]->AddTask(std::make_shared(TaskType::TASK_DISCONNECT, "")); + if (ret == DH_SUCCESS) { + ret = dScreens_[dScreenIdx]->AddTask(std::make_shared(TaskType::TASK_DISABLE, reqId, "")); + } + break; + default: + ret = ERR_DH_SCREEN_SA_DISABLE_FAILED; + break; + } + return ret; +} + +void DScreenManager::RegisterDScreenCallback(const sptr &callback) +{ + DHLOGI("RegisterDScreenCallback"); + dScreenSourceCallbackProxy_ = callback; +} + +std::shared_ptr DScreenManager::FindDScreenByScreenId(uint64_t screenId) +{ + DHLOGD("FindDScreenByScreenId, screenId: %ulld", screenId); + std::lock_guard lock(dScreenMapMtx_); + for (const auto &iter : dScreens_) { + std::shared_ptr dScreen = iter.second; + if (!dScreen) { + continue; + } + + if (dScreen->GetScreenId() == screenId) { + return dScreen; + } + } + DHLOGD("DScreen not found, screenId: %ulld", screenId); + return nullptr; +} + +void DScreenManager::HandleDScreenNotify(const std::string &devId, int32_t eventCode, + const std::string &eventContent) +{ + DHLOGI("HandleDScreenNotify, devId: %s, eventCode: %d", GetAnonyString(devId).c_str(), eventCode); + if (eventCode == NOTIFY_SOURCE_SETUP_RESULT) { + HandleNotifySetUpResult(devId, eventContent); + return; + } + + DHLOGE("invalid eventCode, eventCode: %d", eventCode); +} + +int32_t DScreenManager::NotifyRemoteScreenService(const std::string &devId, int32_t eventCode, + const std::string &eventContent) +{ + DHLOGI("Notify remote sink screen service, remote devId: %s, eventCode: %d", + GetAnonyString(devId).c_str(), eventCode); + sptr remoteSinkSA = GetDScreenSinkSA(devId); + if (!remoteSinkSA) { + DHLOGE("get remote sink sa failed."); + return ERR_DH_SCREEN_SA_GET_REMOTE_SINK_SERVICE_FAIL; + } + std::string localDevId; + int32_t ret = GetLocalDeviceNetworkId(localDevId); + if (ret != DH_SUCCESS) { + DHLOGE("notify remote screen service failed, cannot get local device id"); + return ret; + } + remoteSinkSA->DScreenNotify(localDevId, eventCode, eventContent); + return DH_SUCCESS; +} + +sptr DScreenManager::GetDScreenSinkSA(const std::string &devId) +{ + DHLOGI("GetDScreenSinkSA, devId: %s", GetAnonyString(devId).c_str()); + sptr samgr = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!samgr) { + DHLOGE("Failed to get system ability mgr."); + return nullptr; + } + auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID, devId); + if (remoteObject == nullptr) { + DHLOGE("remoteObject is null"); + return nullptr; + } + + sptr remoteSinkSA = iface_cast(remoteObject); + if (remoteSinkSA == nullptr) { + DHLOGE("Failed to get remote dscreen sink sa"); + return nullptr; + } + return remoteSinkSA; +} + +void DScreenManager::NotifyRemoteSinkSetUp(const std::shared_ptr &dScreen) +{ + DHLOGI("NotifyRemoteSinkSetUp"); + int32_t eventCode = NOTIFY_SINK_SETUP; + std::string devId = dScreen->GetDevId(); + json eventContentJson; + eventContentJson[KEY_SCREEN_ID] = dScreen->GetScreenId(); + eventContentJson[KEY_DH_ID] = dScreen->GetDHId(); + if (dScreen->GetVideoParam() == nullptr) { + DHLOGE("videoParam is null, back to enabled state screedId: %ulld", dScreen->GetScreenId()); + dScreen->SetState(ENABLED); + return; + } + eventContentJson[KEY_VIDEO_PARAM] = *(dScreen->GetVideoParam()); + + if (mapRelations_.count(dScreen->GetScreenId()) == 0) { + DHLOGE("mapRelation not found, back to enabled state screedId: %ulld", dScreen->GetScreenId()); + dScreen->SetState(ENABLED); + return; + } + eventContentJson[KEY_MAPRELATION] = *(mapRelations_[dScreen->GetScreenId()]); + + std::string eventContent = eventContentJson.dump(); + DHLOGD("start notify remote screen, eventContent: %s", eventContent.c_str()); + NotifyRemoteScreenService(devId, eventCode, eventContent); +} + +void DScreenManager::HandleNotifySetUpResult(const std::string &remoteDevId, const std::string &eventContent) +{ + DHLOGI("HandleNotifySetUpResult, remoteDevId:%s", GetAnonyString(remoteDevId).c_str()); + json eventContentJson = json::parse(eventContent, nullptr, false); + if (eventContentJson.is_discarded()) { + DHLOGE("HandleNotifySetUpResult, eventContent is invalid"); + return; + } + + if (!eventContentJson.contains(KEY_DH_ID) || + !eventContentJson.contains(KEY_ERR_CODE) || + !eventContentJson.contains(KEY_ERR_CONTENT)) { + DHLOGE("HandleNotifySetUpResult, eventContent is invalid"); + return; + } + + std::string dhId = eventContentJson[KEY_DH_ID]; + int32_t errCode = eventContentJson[KEY_ERR_CODE]; + std::string errContent = eventContentJson[KEY_ERR_CONTENT]; + + std::string dScreenIdx = remoteDevId + SEPERATOR + dhId; + if (dScreens_.count(dScreenIdx) == 0) { + DHLOGE("dScreen not found, remoteDevId:%s, dhId:%s", + GetAnonyString(remoteDevId).c_str(), GetAnonyString(dhId).c_str()); + return; + } + + if (errCode != DH_SUCCESS) { + DHLOGE("remote sink set up failed, errCode: %d, reason: %s", errCode, errContent.c_str()); + dScreens_[dScreenIdx]->SetState(ENABLED); + return; + } + + dScreens_[dScreenIdx]->AddTask(std::make_shared(TaskType::TASK_CONNECT, "")); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenmgr/src/screen_manager_adapter.cpp b/services/screenservice/sourceservice/dscreenmgr/src/screen_manager_adapter.cpp new file mode 100644 index 00000000..4f0850bf --- /dev/null +++ b/services/screenservice/sourceservice/dscreenmgr/src/screen_manager_adapter.cpp @@ -0,0 +1,130 @@ +/* + * 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 "screen_manager_adapter.h" + +#include + +#include "display_manager.h" +#include "dm_common.h" +#include "screen.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(ScreenMgrAdapter); +ScreenMgrAdapter::~ScreenMgrAdapter() +{ + DHLOGI("~ScreenMgrAdapter"); +} + +uint64_t ScreenMgrAdapter::CreateVirtualScreen(const std::string &devId, const std::string &dhId, + const std::shared_ptr &videoParam) +{ + DHLOGI("CreateVirtualScreen, width: %u, height: %u", videoParam->GetScreenWidth(), + videoParam->GetScreenHeight()); + std::string screenName = DSCREEN_PREFIX + SEPERATOR + devId + SEPERATOR + dhId; + Rosen::VirtualScreenOption option = { + screenName, + videoParam->GetScreenWidth(), + videoParam->GetScreenHeight(), + DEFAULT_DENSITY, + nullptr, + DEFAULT_SCREEN_FLAGS, + false + }; + + uint64_t screenId = Rosen::ScreenManager::GetInstance().CreateVirtualScreen(option); + return screenId; +} + +int32_t ScreenMgrAdapter::RegisterScreenGroupListener(sptr listener) +{ + DHLOGI("RegisterScreenGroupListener"); + if (listenerRegistered) { + DHLOGI("already registered listener."); + return DH_SUCCESS; + } + bool ret = Rosen::ScreenManager::GetInstance().RegisterScreenGroupListener(listener); + if (!ret) { + DHLOGE("RegisterScreenGroupListener Failed."); + return ERR_DH_SCREEN_SA_REGISTER_SCREENLISTENER_FAIL; + } + listenerRegistered = true; + return DH_SUCCESS; +} + +int32_t ScreenMgrAdapter::UnregisterScreenGroupListener(sptr listener) +{ + DHLOGI("UnregisterScreenGroupListener"); + if (!listenerRegistered) { + DHLOGI("listener already unregistered."); + return DH_SUCCESS; + } + bool ret = Rosen::ScreenManager::GetInstance().UnregisterScreenGroupListener(listener); + if (!ret) { + DHLOGE("UnregisterScreenGroupListener Failed."); + return ERR_DH_SCREEN_SA_UNREGISTER_SCREENLISTENER_FAIL; + } + listenerRegistered = false; + return DH_SUCCESS; +} + +void ScreenMgrAdapter::RemoveScreenFromGroup(uint64_t screenId) +{ + DHLOGI("remove screen from group, screenId: %ulld", screenId); + std::vector screenIds; + screenIds.push_back(screenId); + Rosen::ScreenManager::GetInstance().RemoveVirtualScreenFromGroup(screenIds); +} + +int32_t ScreenMgrAdapter::RemoveVirtualScreen(uint64_t screenId) +{ + DHLOGI("remove virtual screen"); + Rosen::DMError err = Rosen::ScreenManager::GetInstance().DestroyVirtualScreen(screenId); + if (err != Rosen::DMError::DM_OK) { + DHLOGE("remove virtual screen failed, screenId:%ulld", screenId); + return ERR_DH_SCREEN_SA_REMOVE_VIRTUALSCREEN_FAIL; + } + return DH_SUCCESS; +} + +int32_t ScreenMgrAdapter::SetImageSurface(uint64_t screenId, sptr surface) +{ + DHLOGI("SetImageSurface for virtualscreen, screenId: %ulld", screenId); + Rosen::ScreenManager::GetInstance().SetVirtualScreenSurface(screenId, surface); + return DH_SUCCESS; +} + +std::shared_ptr ScreenMgrAdapter::GetMapRelation(uint64_t screenId) +{ + DHLOGI("GetMapRelation"); + std::shared_ptr mapRelation = std::make_shared(); + sptr screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId); + sptr display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay(); + mapRelation->SetDisplayId(display->GetId()); + mapRelation->SetScreenId(screenId); + + ScreenRect screenRect = {0, 0, screen->GetWidth(), screen->GetHeight()}; + DisplayRect displayRect = {0, 0, display->GetWidth(), display->GetHeight()}; + mapRelation->SetDisplayRect(displayRect); + mapRelation->SetScreenRect(screenRect); + return mapRelation; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/include/callback/dscreen_source_callback_proxy.h b/services/screenservice/sourceservice/dscreenservice/include/callback/dscreen_source_callback_proxy.h new file mode 100644 index 00000000..aec646c2 --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/include/callback/dscreen_source_callback_proxy.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_CALLBACK_PROXY_H +#define OHOS_DSCREEN_SOURCE_CALLBACK_PROXY_H + +#include "iremote_proxy.h" + +#include "idscreen_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceCallbackProxy : public IRemoteProxy { +public: + explicit DScreenSourceCallbackProxy(const sptr impl) + : IRemoteProxy(impl) + { + } + + ~DScreenSourceCallbackProxy() {} + int32_t OnNotifyRegResult(const std::string &devId, const std::string &dhId, const std::string &reqId, + int32_t status, const std::string &resultData) override; + int32_t OnNotifyUnregResult(const std::string &devId, const std::string &dhId, const std::string &reqId, + int32_t status, const std::string &resultData) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif diff --git a/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_service.h b/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_service.h new file mode 100644 index 00000000..b2731fb9 --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_service.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_SERVICE_H +#define OHOS_DSCREEN_SOURCE_SERVICE_H + +#include "system_ability.h" +#include "ipc_object_stub.h" + +#include "dscreen_manager.h" +#include "dscreen_source_stub.h" +#include "idscreen_source_callback.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceService : public SystemAbility, public DScreenSourceStub, + public std::enable_shared_from_this { +DECLARE_SYSTEM_ABILITY(DScreenSourceService); +public: + DScreenSourceService(int32_t saId, bool runOnCreate); + ~DScreenSourceService(); + int32_t InitSource(const std::string ¶ms, const sptr &callback) override; + int32_t ReleaseSource() override; + int32_t RegisterDistributedHardware(const std::string &devId, const std::string &dhId, + const EnableParam ¶m, const std::string &reqId) override; + int32_t UnregisterDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &reqId) override; + int32_t ConfigDistributedHardware(const std::string &devId, const std::string &dhId, const std::string &key, + const std::string &value) override; + void DScreenNotify(const std::string &devId, const int32_t eventCode, const std::string &eventContent) override; + +protected: + void OnStart() override; + void OnStop() override; + DISALLOW_COPY_AND_MOVE(DScreenSourceService); + +private: + bool Init(); + + sptr dScreenSourceCallbackProxy_ = nullptr; + bool registerToService_ = false; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_stub.h b/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_stub.h new file mode 100644 index 00000000..59c4fd9e --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/include/dscreen_source_stub.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DSCREEN_SOURCE_STUB_H +#define OHOS_DSCREEN_SOURCE_STUB_H + +#include +#include "iremote_stub.h" +#include "idscreen_source.h" + +namespace OHOS { +namespace DistributedHardware { +class DScreenSourceStub : public IRemoteStub { +public: + DScreenSourceStub(); + virtual ~DScreenSourceStub(); + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; + +private: + int32_t InitSourceInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t ReleaseSourceInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t RegisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t UnregisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t ConfigDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + int32_t DScreenNotifyInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + + using DScreenSourceFunc = int32_t (DScreenSourceStub::*)(MessageParcel &data, MessageParcel &reply, + MessageOption &option); + std::map memberFuncMap_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/src/callback/dscreen_source_callback_proxy.cpp b/services/screenservice/sourceservice/dscreenservice/src/callback/dscreen_source_callback_proxy.cpp new file mode 100644 index 00000000..fd099abe --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/src/callback/dscreen_source_callback_proxy.cpp @@ -0,0 +1,74 @@ +/* + * 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 "dscreen_source_callback_proxy.h" + +#include "parcel.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t DScreenSourceCallbackProxy::OnNotifyRegResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &resultData) +{ + DHLOGD("OnNotifyRegResult, devId: %s, dhId: %s, reqId: %s, status: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), status); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed."); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) || + !data.WriteString(reqId) || !data.WriteInt32(status) || + !data.WriteString(resultData)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(NOTIFY_REG_RESULT, data, reply, option); + return reply.ReadInt32(); +} + +int32_t DScreenSourceCallbackProxy::OnNotifyUnregResult(const std::string &devId, const std::string &dhId, + const std::string &reqId, int32_t status, const std::string &resultData) +{ + DHLOGD("OnNotifyUnregResult, devId: %s, dhId: %s, reqId: %s, status: %d", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), status); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + DHLOGE("WriteInterfaceToken failed."); + return ERR_DH_SCREEN_SA_WRITEINTERFACETOKEN_FAILED; + } + + if (!data.WriteString(devId) || !data.WriteString(dhId) || + !data.WriteString(reqId) || !data.WriteInt32(status) || + !data.WriteString(resultData)) { + DHLOGE("Write param failed."); + return ERR_DH_SCREEN_SA_WRITEPARAM_FAILED; + } + + Remote()->SendRequest(NOTIFY_UNREG_RESULT, data, reply, option); + return reply.ReadInt32(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp new file mode 100644 index 00000000..68220f09 --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp @@ -0,0 +1,142 @@ +/* + * 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 "dscreen_source_service.h" + +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +REGISTER_SYSTEM_ABILITY_BY_ID(DScreenSourceService, DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID, true); + +DScreenSourceService::DScreenSourceService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +{ + DHLOGI("dscreen source service create."); +} + +DScreenSourceService::~DScreenSourceService() +{ + DHLOGI("~DScreenSourceService."); +} + +void DScreenSourceService::OnStart() +{ + DHLOGI("dscreen source service start."); + Init(); +} + +void DScreenSourceService::OnStop() +{ + DHLOGI("dscreen source service stop."); + dScreenSourceCallbackProxy_ = nullptr; + registerToService_ = false; +} + +bool DScreenSourceService::Init() +{ + DHLOGI("dscreen source service start init."); + if (!registerToService_) { + bool ret = Publish(this); + if (!ret) { + DHLOGE("dscreen source publish service failed."); + return false; + } + registerToService_ = true; + } + DHLOGI("dscreen init success."); + return true; +} + +int32_t DScreenSourceService::InitSource(const std::string ¶ms, const sptr &callback) +{ + DHLOGI("InitSource"); + dScreenSourceCallbackProxy_ = callback; + int32_t ret = DScreenManager::GetInstance().Init(); + if (ret != DH_SUCCESS) { + DHLOGE("Init DScreenManager failed. err: %d", ret); + return ret; + } + + DScreenManager::GetInstance().RegisterDScreenCallback(callback); + return DH_SUCCESS; +} + +int32_t DScreenSourceService::ReleaseSource() +{ + DHLOGI("ReleaseSource"); + dScreenSourceCallbackProxy_ = nullptr; + int32_t ret = DScreenManager::GetInstance().UnInit(); + if (ret != DH_SUCCESS) { + DHLOGE("UnInit DScreenManager failed. err: %d", ret); + return ret; + } + return DH_SUCCESS; +} + +int32_t DScreenSourceService::RegisterDistributedHardware(const std::string &devId, const std::string &dhId, + const EnableParam ¶m, const std::string &reqId) +{ + DHLOGI("RegisterDistributedHardware"); + std::string version = param.version; + std::string attrs = param.attrs; + DHLOGD("enable distributedScreen. devId: %s, dhId: %s, reqId: %s, attrs: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), attrs.c_str()); + int ret = DScreenManager::GetInstance().EnableDistributedScreen(devId, dhId, attrs, reqId); + if (ret != DH_SUCCESS) { + DHLOGE("enable distributedScreen failed. devId: %s, dhId: %s, reqId: %s, attrs: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), attrs.c_str()); + return ERR_DH_SCREEN_SA_ENABLE_FAILED; + } + return DH_SUCCESS; +} + +int32_t DScreenSourceService::UnregisterDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &reqId) +{ + DHLOGI("UnregisterDistributedHardware"); + int ret = DScreenManager::GetInstance().DisableDistributedScreen(devId, dhId, reqId); + if (ret != DH_SUCCESS) { + DHLOGE("disable distributedScreen failed. devId: %s, dhId: %s, reqId: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str()); + return ERR_DH_SCREEN_SA_DISABLE_FAILED; + } + return DH_SUCCESS; +} + +int32_t DScreenSourceService::ConfigDistributedHardware(const std::string &devId, const std::string &dhId, + const std::string &key, const std::string &value) +{ + DHLOGI("ConfigDistributedHardware"); + return DH_SUCCESS; +} + +void DScreenSourceService::DScreenNotify(const std::string &devId, const int32_t eventCode, + const std::string &eventContent) +{ + DHLOGI("DScreenNotify, devId: %s, eventCode: %d", GetAnonyString(devId).c_str(), eventCode); + DScreenManager::GetInstance().HandleDScreenNotify(devId, eventCode, eventContent); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_stub.cpp b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_stub.cpp new file mode 100644 index 00000000..23630c5a --- /dev/null +++ b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_stub.cpp @@ -0,0 +1,146 @@ +/* + * 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 "dscreen_source_stub.h" + +#include "iservice_registry.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_source_callback_proxy.h" + +namespace OHOS { +namespace DistributedHardware { +DScreenSourceStub::DScreenSourceStub() +{ + DHLOGI("DScreenSourceStub construct."); + memberFuncMap_[INIT_SOURCE] = &DScreenSourceStub::InitSourceInner; + memberFuncMap_[RELEASE_SOURCE] = &DScreenSourceStub::ReleaseSourceInner; + memberFuncMap_[REGISTER_DISTRIBUTED_HARDWARE] = &DScreenSourceStub::RegisterDistributedHardwareInner; + memberFuncMap_[UNREGISTER_DISTRIBUTED_HARDWARE] = &DScreenSourceStub::UnregisterDistributedHardwareInner; + memberFuncMap_[CONFIG_DISTRIBUTED_HARDWARE] = &DScreenSourceStub::ConfigDistributedHardwareInner; + memberFuncMap_[DSCREEN_NOTIFY] = &DScreenSourceStub::DScreenNotifyInner; +} + +DScreenSourceStub::~DScreenSourceStub() +{ + DHLOGI("DScreenSourceStub deconstruct."); +} + +int32_t DScreenSourceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("OnRemoteRequest, code: %d", code); + std::u16string desc = DScreenSourceStub::GetDescriptor(); + std::u16string remoteDesc = data.ReadInterfaceToken(); + if (desc != remoteDesc) { + DHLOGE("DScreenSourceStub::OnRemoteRequest remoteDesc is invalid!"); + return ERR_INVALID_DATA; + } + + std::map::iterator iter = memberFuncMap_.find(code); + if (iter == memberFuncMap_.end()) { + DHLOGE("invalid request code."); + return ERR_DH_SCREEN_SA_REQUEST_CODE_INVALID; + } + DScreenSourceFunc &func = iter->second; + return (this->*func)(data, reply, option); +} + +int32_t DScreenSourceStub::InitSourceInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("InitSourceInner"); + std::string param = data.ReadString(); + sptr remoteObject = data.ReadRemoteObject(); + if (remoteObject == nullptr) { + DHLOGE("Read param failed."); + return ERR_DH_SCREEN_SA_READPARAM_FAILED; + } + + sptr dScreenSourceCallbackProxy(new DScreenSourceCallbackProxy(remoteObject)); + int32_t ret = InitSource(param, dScreenSourceCallbackProxy); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSourceStub::ReleaseSourceInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("ReleaseSourceInner"); + int32_t ret = ReleaseSource(); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSourceStub::RegisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("RegisterDistributedHardwareInner"); + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string version = data.ReadString(); + std::string attrs = data.ReadString(); + std::string reqId = data.ReadString(); + EnableParam enableParam; + enableParam.version = version; + enableParam.attrs = attrs; + + int32_t ret = RegisterDistributedHardware(devId, dhId, enableParam, reqId); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSourceStub::UnregisterDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("RegisterDistributedHardwareInner"); + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string reqId = data.ReadString(); + + int32_t ret = UnregisterDistributedHardware(devId, dhId, reqId); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSourceStub::ConfigDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("ConfigDistributedHardwareInner"); + std::string devId = data.ReadString(); + std::string dhId = data.ReadString(); + std::string key = data.ReadString(); + std::string value = data.ReadString(); + + int32_t ret = ConfigDistributedHardware(devId, dhId, key, value); + reply.WriteInt32(ret); + return DH_SUCCESS; +} + +int32_t DScreenSourceStub::DScreenNotifyInner(MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + DHLOGI("DScreenNotifyInner"); + std::string devId = data.ReadString(); + int32_t eventCode = data.ReadInt32(); + std::string eventContent = data.ReadString(); + + DScreenNotify(devId, eventCode, eventContent); + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screendatachannel/include/screen_data_channel_impl.h b/services/screentransport/screendatachannel/include/screen_data_channel_impl.h new file mode 100644 index 00000000..9ec16416 --- /dev/null +++ b/services/screentransport/screendatachannel/include/screen_data_channel_impl.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_DATA_CHANNEL_IMPL_H +#define OHOS_SCREEN_DATA_CHANNEL_IMPL_H + +#include +#include + +#include "data_buffer.h" +#include "iscreen_channel.h" +#include "softbus_adapter.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenDataChannelImpl : public IScreenChannel, + public ISoftbusListener, + public std::enable_shared_from_this { +public: + ScreenDataChannelImpl(std::string peerDevId) : peerDevId_(peerDevId) {}; + ~ScreenDataChannelImpl() = default; + + int32_t CreateSession(const std::shared_ptr &listener) override; + int32_t ReleaseSession() override; + int32_t OpenSession() override; + int32_t CloseSession() override; + int32_t SendData(const std::shared_ptr &screenData) override; + + void OnSessionOpened(int32_t sessionId, int32_t result) override; + void OnSessionClosed(int32_t sessionId) override; + void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) override; + void OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) override; + +private: + static const constexpr char *LOG_TAG = "ScreenDataChannel"; + + const std::string peerDevId_; + int32_t sessionId_ = 0; + std::weak_ptr channelListener_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp new file mode 100644 index 00000000..6097c4a5 --- /dev/null +++ b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp @@ -0,0 +1,197 @@ +/* + * 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 "screen_data_channel_impl.h" + +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ScreenDataChannelImpl::CreateSession(const std::shared_ptr &listener) +{ + DHLOGI("%s: CreateSession, peerDevId(%s)", LOG_TAG, GetAnonyString(peerDevId_).c_str()); + if (!listener) { + DHLOGE("%s: Channel listener is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = + SoftbusAdapter::GetInstance().CreateSoftbusSessionServer(PKG_NAME, DATA_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Create softbus session failed ret: %d.", LOG_TAG, ret); + return ret; + } + + std::shared_ptr softbusListener = shared_from_this(); + ret = SoftbusAdapter::GetInstance().RegisterSoftbusListener(softbusListener, DATA_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register softbus adapter listener failed ret: %d.", LOG_TAG, ret); + return ret; + } + + channelListener_ = listener; + DHLOGI("%s: Create softbus session success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenDataChannelImpl::ReleaseSession() +{ + DHLOGI("%s: ReleaseSession, peerDevId(%s)", LOG_TAG, GetAnonyString(peerDevId_).c_str()); + int32_t ret = SoftbusAdapter::GetInstance().RemoveSoftbusSessionServer(PKG_NAME, DATA_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Release softbus session failed ret: %d.", LOG_TAG, ret); + return ret; + } + + ret = SoftbusAdapter::GetInstance().UnRegisterSoftbusListener(DATA_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: UnRegister softbus adapter listener failed ret: %d.", LOG_TAG, ret); + return ret; + } + + DHLOGI("%s: Release softbus session success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenDataChannelImpl::OpenSession() +{ + DHLOGI("%s: OpenSession, peerDevId(%s)", LOG_TAG, GetAnonyString(peerDevId_).c_str()); + int32_t sessionId = + SoftbusAdapter::GetInstance().OpenSoftbusSession(DATA_SESSION_NAME, DATA_SESSION_NAME, peerDevId_); + if (sessionId < 0) { + DHLOGE("%s: Open screen session failed, ret: %d", LOG_TAG, sessionId); + return ERR_DH_SCREEN_TRANS_ERROR; + } + sessionId_ = sessionId; + + DHLOGI("%s: Open screen session success, sessionId(%d)", LOG_TAG, sessionId_); + return DH_SUCCESS; +} + +int32_t ScreenDataChannelImpl::CloseSession() +{ + DHLOGI("%s: CloseSession, sessionId(%d)", LOG_TAG, sessionId_); + if (sessionId_ == 0) { + DHLOGD("%s: Session is not opened.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN; + } + + int32_t ret = SoftbusAdapter::GetInstance().CloseSoftbusSession(sessionId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Close screen session failed ret: %d.", LOG_TAG, ret); + return ret; + } + sessionId_ = 0; + + DHLOGI("%s: Close screen session success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenDataChannelImpl::SendData(const std::shared_ptr &screenData) +{ + DHLOGD("%s: SendData, sessionId(%d)", LOG_TAG, sessionId_); + if (!screenData) { + DHLOGE("%s: Screen data is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + StreamData data = {(char *)screenData->Data(), screenData->Capacity()}; + StreamData ext = {0}; + StreamFrameInfo frameInfo = {0}; + + int32_t ret = SoftbusAdapter::GetInstance().SendSoftbusStream(sessionId_, &data, &ext, &frameInfo); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Send screen data failed ret: %d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +void ScreenDataChannelImpl::OnSessionOpened(int32_t sessionId, int32_t result) +{ + DHLOGI("%s: OnScreenSessionOpened, sessionId: %d, result: %d", LOG_TAG, sessionId, result); + if (result != 0) { + DHLOGE("Session open failed.", LOG_TAG); + return; + } + + std::shared_ptr listener = channelListener_.lock(); + if (!listener) { + DHLOGE("%s: Channel listener is null", LOG_TAG); + return; + } + listener->OnSessionOpened(); + sessionId_ = sessionId; +} + +void ScreenDataChannelImpl::OnSessionClosed(int32_t sessionId) +{ + DHLOGI("%s: OnScreenSessionClosed, sessionId(%d).", LOG_TAG, sessionId); + std::shared_ptr listener = channelListener_.lock(); + if (!listener) { + DHLOGE("%s: Channel listener is null", LOG_TAG); + return; + } + listener->OnSessionClosed(); +} + +void ScreenDataChannelImpl::OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + (void) sessionId; + (void) data; + (void) dataLen; + + DHLOGD("%s: OnScreenBytesReceived data channel not support yet.", LOG_TAG); +} + +void ScreenDataChannelImpl::OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + (void)ext; + (void)param; + + if (data == nullptr) { + DHLOGE("%s: Stream data is null.", LOG_TAG); + return; + } + + std::shared_ptr listener = channelListener_.lock(); + if (!listener) { + DHLOGE("%s: Channel listener is null.", LOG_TAG); + return; + } + + DHLOGI("%s: OnScreenStreamReceived, sessionId(%d) dataSize(%zu).", LOG_TAG, sessionId, data->bufLen); + auto dataBuffer = std::make_shared(data->bufLen); + if (!dataBuffer) { + DHLOGE("%s: DataBuffer is null.", LOG_TAG); + return; + } + + int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), (uint8_t *)data->buf, data->bufLen); + if (ret != EOK) { + DHLOGE("%s: Data memcpy_s failed.", LOG_TAG); + return; + } + listener->OnDataReceived(dataBuffer); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/decoder/include/image_decoder_callback.h b/services/screentransport/screensinkprocessor/decoder/include/image_decoder_callback.h new file mode 100644 index 00000000..939205ab --- /dev/null +++ b/services/screentransport/screensinkprocessor/decoder/include/image_decoder_callback.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 OHOS_IMAGE_DECODER_CALLBACK_H +#define OHOS_IMAGE_DECODER_CALLBACK_H + +#include + +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSinkDecoder; +class ImageDecoderCallback : public Media::AVCodecCallback { +public: + explicit ImageDecoderCallback(const std::shared_ptr &decoder) + : videoDecoder_(decoder) {}; + ~ImageDecoderCallback() = default; + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode) override; + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag) override; + void OnInputBufferAvailable(uint32_t index) override; + void OnOutputFormatChanged(const Media::Format &format) override; + +private: + static const constexpr char *LOG_TAG = "ImageDecoderCallback"; + + std::weak_ptr videoDecoder_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h b/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h new file mode 100644 index 00000000..fa17b5a1 --- /dev/null +++ b/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IMAGE_SINK_DECODER_H +#define OHOS_IMAGE_SINK_DECODER_H + +#include +#include +#include +#include + +#include "avsharedmemory.h" +#include "avcodec_common.h" +#include "avcodec_video_decoder.h" +#include "media_errors.h" +#include "format.h" +#include "surface.h" + +#include "data_buffer.h" +#include "iimage_sink_processor_listener.h" +#include "image_decoder_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSinkDecoder : public std::enable_shared_from_this { +public: + ImageSinkDecoder(const std::shared_ptr &imageListener) + : imageProcessorListener_(imageListener) {}; + ~ImageSinkDecoder() = default; + + int32_t ConfigureDecoder(const VideoParam &configParam); + int32_t ReleaseDecoder(); + int32_t StartDecoder(); + int32_t StopDecoder(); + int32_t SetOutputSurface(sptr &surface); + int32_t InputScreenData(const std::shared_ptr &data); + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode); + void OnInputBufferAvailable(uint32_t index); + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag); + void OnOutputFormatChanged(const Media::Format &format); + +private: + int32_t SetDecoderFormat(const VideoParam &configParam); + int32_t InitVideoDecoder(const VideoParam &configParam); + int32_t StartInputThread(); + int32_t StopInputThread(); + void DecodeScreenData(); + int32_t ProcessData(const std::shared_ptr &screenData, const int32_t bufferIndex); + +private: + static const constexpr char *LOG_TAG = "ImageSinkDecoder"; + static constexpr uint32_t DECODE_WAIT_MILLISECONDS = 5000; + static constexpr size_t DATA_QUEUE_MAX_SIZE = 10; + + std::mutex dataMutex_; + std::mutex decodeMutex_; + std::thread decodeThread_; + std::condition_variable decodeCond_; + + Media::Format imageFormat_; + Media::AVCodecBufferInfo decoderBufferInfo_; + + bool isDecoderReady_ = false; + std::queue> videoDataQueue_; + std::queue bufferIndexQueue_; + std::shared_ptr videoDecoder_; + std::shared_ptr decodeVideoCallback_; + std::weak_ptr imageProcessorListener_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/decoder/src/image_decoder_callback.cpp b/services/screentransport/screensinkprocessor/decoder/src/image_decoder_callback.cpp new file mode 100644 index 00000000..b19fb870 --- /dev/null +++ b/services/screentransport/screensinkprocessor/decoder/src/image_decoder_callback.cpp @@ -0,0 +1,68 @@ +/* + * 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 "image_decoder_callback.h" + +#include "dscreen_log.h" +#include "image_sink_decoder.h" + +namespace OHOS { +namespace DistributedHardware { +void ImageDecoderCallback::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGD("%s: OnError.", LOG_TAG); + std::shared_ptr decoder = videoDecoder_.lock(); + if (decoder == nullptr) { + DHLOGE("decoder is nullptr."); + return; + } + decoder->OnError(errorType, errorCode); +} + +void ImageDecoderCallback::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGD("%s: OnOutputBufferAvailable.", LOG_TAG); + std::shared_ptr decoder = videoDecoder_.lock(); + if (decoder == nullptr) { + DHLOGE("decoder is nullptr."); + return; + } + decoder->OnOutputBufferAvailable(index, info, flag); +} + +void ImageDecoderCallback::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("%s: OnInputBufferAvailable.", LOG_TAG); + std::shared_ptr decoder = videoDecoder_.lock(); + if (decoder == nullptr) { + DHLOGE("decoder is nullptr."); + return; + } + decoder->OnInputBufferAvailable(index); +} + +void ImageDecoderCallback::OnOutputFormatChanged(const Media::Format &format) +{ + DHLOGD("%s: OnOutputFormatChanged.", LOG_TAG); + std::shared_ptr decoder = videoDecoder_.lock(); + if (decoder == nullptr) { + DHLOGE("decoder is nullptr."); + return; + } + decoder->OnOutputFormatChanged(format); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp b/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp new file mode 100644 index 00000000..ea167bf7 --- /dev/null +++ b/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp @@ -0,0 +1,346 @@ +/* + * 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 "image_sink_decoder.h" + +#include +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ImageSinkDecoder::ConfigureDecoder(const VideoParam &configParam) +{ + DHLOGI("%s: ConfigureDecoder.", LOG_TAG); + int32_t ret = InitVideoDecoder(configParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: InitVideoDecoder failed.", LOG_TAG); + return ret; + } + + ret = SetDecoderFormat(configParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetDecoderFormat failed.", LOG_TAG); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::ReleaseDecoder() +{ + DHLOGI("%s: ReleaseDecoder.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoDecoder_->Release(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: ReleaseDecoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_RELEASE_FAILED; + } + decodeVideoCallback_ = nullptr; + videoDecoder_ = nullptr; + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::StartDecoder() +{ + DHLOGI("%s: StartDecoder.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoDecoder_->Prepare(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Prepare decoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_PREPARE_FAILED; + } + + ret = videoDecoder_->Start(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Start decoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_START_FAILED; + } + StartInputThread(); + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::StopDecoder() +{ + DHLOGI("%s: StopDecoder.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoDecoder_->Flush(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Flush decoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_FLUSH_FAILED; + } + + ret = videoDecoder_->Stop(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Stop decoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_STOP_FAILED; + } + StopInputThread(); + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::InitVideoDecoder(const VideoParam &configParam) +{ + DHLOGI("%s: InitVideoDecoder.", LOG_TAG); + switch (configParam.GetCodecType()) { + case VIDEO_CODEC_TYPE_VIDEO_H264: + videoDecoder_ = Media::VideoDecoderFactory::CreateByName("OMX_hisi_video_decoder_avc"); + break; + case VIDEO_CODEC_TYPE_VIDEO_H265: + videoDecoder_ = Media::VideoDecoderFactory::CreateByMime("video/hevc"); + break; + default: + DHLOGE("%s: codecType is invalid!", LOG_TAG); + videoDecoder_ = nullptr; + } + + if (videoDecoder_ == nullptr) { + DHLOGE("%s: Create videoEncode failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + decodeVideoCallback_ = std::make_shared(shared_from_this()); + int32_t ret = videoDecoder_->SetCallback(decodeVideoCallback_); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Set decoder callback failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SET_CALLBACK_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::SetDecoderFormat(const VideoParam &configParam) +{ + DHLOGI("%s: SetDecoderFormat.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + switch (configParam.GetCodecType()) { + case VIDEO_CODEC_TYPE_VIDEO_H264: + imageFormat_.PutStringValue("codec_mime", "video/avc"); + break; + case VIDEO_CODEC_TYPE_VIDEO_H265: + imageFormat_.PutStringValue("codec_mime", "video/hevc"); + break; + default: + DHLOGE("The current codec type does not support decoding."); + return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION; + } + switch (configParam.GetVideoFormat()) { + case VIDEO_DATA_FORMAT_YUVI420: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::YUVI420); + break; + case VIDEO_DATA_FORMAT_NV12: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12); + break; + case VIDEO_DATA_FORMAT_NV21: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV21); + break; + default: + DHLOGE("The current pixel format does not support decoding."); + return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION; + } + + imageFormat_.PutLongValue("max_input_size", MAX_YUV420_BUFFER_SIZE); + imageFormat_.PutIntValue("width", configParam.GetVideoWidth()); + imageFormat_.PutIntValue("height", configParam.GetVideoHeight()); + imageFormat_.PutIntValue("frame_rate", configParam.GetFps()); + + int32_t ret = videoDecoder_->Configure(imageFormat_); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: configure decoder format param failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_CONFIGURE_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::SetOutputSurface(sptr &surface) +{ + DHLOGI("%s: SetOutputSurface.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoDecoder_->SetOutputSurface(surface); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: SetOutputSurface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::InputScreenData(const std::shared_ptr &data) +{ + DHLOGD("%s: InputScreenData.", LOG_TAG); + std::lock_guard dataLock(dataMutex_); + while (videoDataQueue_.size() >= DATA_QUEUE_MAX_SIZE) { + DHLOGE("%s: videoData queue overflow.", LOG_TAG); + videoDataQueue_.pop(); + } + videoDataQueue_.push(data); + decodeCond_.notify_all(); + + return DH_SUCCESS; +} + +void ImageSinkDecoder::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGI("%s: OnImageDecodeError, errorType(%d), errorCode(%d)", LOG_TAG, errorType, errorCode); + std::shared_ptr listener = imageProcessorListener_.lock(); + if (!listener) { + DHLOGE("%s: Listener is null.", LOG_TAG); + return; + } + listener->OnProcessorStateNotify(errorCode); +} + +void ImageSinkDecoder::OnInputBufferAvailable(uint32_t index) +{ + DHLOGI("%s: OnDecodeInputBufferAvailable: %u.", LOG_TAG, index); + std::lock_guard dataLock(dataMutex_); + bufferIndexQueue_.push(index); +} + +void ImageSinkDecoder::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGI("%s: OnDecodeOutputBufferAvailable.", LOG_TAG); + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return; + } + + decoderBufferInfo_ = info; + int32_t ret = videoDecoder_->ReleaseOutputBuffer(index, true); + if (ret != Media::MSERR_OK) { + DHLOGD("%s: ReleaseOutputBuffer failed.", LOG_TAG); + } +} + +void ImageSinkDecoder::OnOutputFormatChanged(const Media::Format &format) +{ + (void) format; +} + +int32_t ImageSinkDecoder::StartInputThread() +{ + DHLOGI("%s: StartInputThread.", LOG_TAG); + isDecoderReady_ = true; + decodeThread_ = std::thread(&ImageSinkDecoder::DecodeScreenData, this); + + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::StopInputThread() +{ + DHLOGI("%s: StopInputThread.", LOG_TAG); + isDecoderReady_ = false; + decodeThread_.join(); + std::lock_guard dataLock(dataMutex_); + while (!bufferIndexQueue_.empty()) { + bufferIndexQueue_.pop(); + } + while (!videoDataQueue_.empty()) { + videoDataQueue_.pop(); + } + + return DH_SUCCESS; +} + +void ImageSinkDecoder::DecodeScreenData() +{ + while (isDecoderReady_) { + std::shared_ptr screenData; + int32_t bufferIndex = 0; + { + std::unique_lock lock(dataMutex_); + decodeCond_.wait_for(lock, std::chrono::milliseconds(DECODE_WAIT_MILLISECONDS), + [this]() { return (!videoDataQueue_.empty() && !bufferIndexQueue_.empty()); }); + + if (videoDataQueue_.empty() || bufferIndexQueue_.empty()) { + DHLOGD("%s: Index queue or data queue is empty.", LOG_TAG); + continue; + } + bufferIndex = bufferIndexQueue_.front(); + bufferIndexQueue_.pop(); + screenData = videoDataQueue_.front(); + videoDataQueue_.pop(); + } + + int32_t ret = ProcessData(screenData, bufferIndex); + if (ret == ERR_DH_SCREEN_TRANS_NULL_VALUE) { + return; + } else if (ret != DH_SUCCESS) { + continue; + } + } +} + +int32_t ImageSinkDecoder::ProcessData(const std::shared_ptr &screenData, const int32_t bufferIndex) +{ + if (!videoDecoder_) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + auto inputBuffer = videoDecoder_->GetInputBuffer(bufferIndex); + if (inputBuffer == nullptr) { + DHLOGE("%s: GetInputBuffer failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + int32_t ret = memcpy_s(inputBuffer->GetBase(), inputBuffer->GetSize(), screenData->Data(), screenData->Capacity()); + if (ret != EOK) { + DHLOGE("%s: Copy data failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + DHLOGD("%s: Decode screen data.", LOG_TAG); + Media::AVCodecBufferInfo bufferInfo; + bufferInfo.presentationTimeUs = 0; + bufferInfo.size = static_cast(screenData->Capacity()); + bufferInfo.offset = 0; + ret = videoDecoder_->QueueInputBuffer(bufferIndex, bufferInfo, Media::AVCODEC_BUFFER_FLAG_NONE); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: QueueInputBuffer failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/screentransport/screensinkprocessor/include/iimage_sink_processor.h b/services/screentransport/screensinkprocessor/include/iimage_sink_processor.h new file mode 100644 index 00000000..6deed5fa --- /dev/null +++ b/services/screentransport/screensinkprocessor/include/iimage_sink_processor.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IIMAGE_SINK_PROCESSOR_H +#define OHOS_IIMAGE_SINK_PROCESSOR_H + +#include + +#include "surface.h" + +#include "data_buffer.h" +#include "video_param.h" +#include "iimage_sink_processor_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class IImageSinkProcessor { +public: + virtual ~IImageSinkProcessor() = default; + + virtual int32_t ConfigureImageProcessor(const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &listener) = 0; + virtual int32_t ReleaseImageProcessor() = 0; + virtual int32_t StartImageProcessor() = 0; + virtual int32_t StopImageProcessor() = 0; + virtual int32_t SetImageSurface(sptr &surface) = 0; + virtual int32_t ProcessImage(const std::shared_ptr &data) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/include/iimage_sink_processor_listener.h b/services/screentransport/screensinkprocessor/include/iimage_sink_processor_listener.h new file mode 100644 index 00000000..120881d3 --- /dev/null +++ b/services/screentransport/screensinkprocessor/include/iimage_sink_processor_listener.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 OHOS_IIMAGE_SINK_PROCESSOR_LISTENER_H +#define OHOS_IIMAGE_SINK_PROCESSOR_LISTENER_H + +namespace OHOS { +namespace DistributedHardware { +class IImageSinkProcessorListener { +public: + virtual ~IImageSinkProcessorListener() = default; + + virtual void OnProcessorStateNotify(int32_t state) = 0; +}; +} // namespace DistributedHardware +} // namsspace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/include/image_sink_processor.h b/services/screentransport/screensinkprocessor/include/image_sink_processor.h new file mode 100644 index 00000000..8929a74b --- /dev/null +++ b/services/screentransport/screensinkprocessor/include/image_sink_processor.h @@ -0,0 +1,47 @@ +/* + * 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 IMAGE_SINK_PROCESSOR_H +#define IMAGE_SINK_PROCESSOR_H + +#include "iimage_sink_processor.h" +#include "image_sink_decoder.h" +#include "video_param.h" +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSinkProcessor : public IImageSinkProcessor { +public: + ImageSinkProcessor() = default; + ~ImageSinkProcessor() = default; + + int32_t ConfigureImageProcessor(const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &imageListener) override; + int32_t ReleaseImageProcessor() override; + int32_t StartImageProcessor() override; + int32_t StopImageProcessor() override; + int32_t SetImageSurface(sptr &surface) override; + int32_t ProcessImage(const std::shared_ptr &data) override; + +private: + static const constexpr char *LOG_TAG = "ImageSinkProcessor"; + VideoParam localParam_; + VideoParam remoteParam_; + std::shared_ptr imageDecoder_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp b/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp new file mode 100644 index 00000000..6572255e --- /dev/null +++ b/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp @@ -0,0 +1,131 @@ +/* + * 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 "image_sink_processor.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ImageSinkProcessor::ConfigureImageProcessor( + const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &imageListener) +{ + DHLOGI("%s: ConfigureImageProcessor.", LOG_TAG); + localParam_ = localParam; + remoteParam_ = remoteParam; + + imageDecoder_ = std::make_shared(imageListener); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->ConfigureDecoder(localParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: ConfigureDecoder failed ret:%d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkProcessor::ReleaseImageProcessor() +{ + DHLOGI("%s: ReleaseImageProcessor.", LOG_TAG); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->ReleaseDecoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: ReleaseDecoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ERROR; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkProcessor::StartImageProcessor() +{ + DHLOGI("%s: StartImageProcessor.", LOG_TAG); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->StartDecoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: StartDecoder failed ret:%d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkProcessor::StopImageProcessor() +{ + DHLOGI("%s: StopImageProcessor.", LOG_TAG); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->StopDecoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: StopDecoder failed ret:%d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkProcessor::SetImageSurface(sptr &surface) +{ + DHLOGI("%s: SetImageSurface.", LOG_TAG); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->SetOutputSurface(surface); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetOutputSurface failed ret:%d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSinkProcessor::ProcessImage(const std::shared_ptr &data) +{ + DHLOGI("%s: ProcessImage.", LOG_TAG); + if (imageDecoder_ == nullptr) { + DHLOGE("%s: Decoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageDecoder_->InputScreenData(data); + if (ret != DH_SUCCESS) { + DHLOGE("%s: InputScreenData failed ret:%d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensinktrans/BUILD.gn b/services/screentransport/screensinktrans/BUILD.gn new file mode 100644 index 00000000..0db390a5 --- /dev/null +++ b/services/screentransport/screensinktrans/BUILD.gn @@ -0,0 +1,70 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_sinktrans") { + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/softbusadapter/include", + ] + + sources = [ + "./src/screen_sink_trans.cpp", + "${services_path}/common/databuffer/src/data_buffer.cpp", + "${services_path}/common/utils/src/video_param.cpp", + "${services_path}/screentransport/screendatachannel/src/screen_data_channel_impl.cpp", + "${services_path}/screentransport/screensinkprocessor/src/image_sink_processor.cpp", + "${services_path}/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp", + "${services_path}/screentransport/screensinkprocessor/decoder/src/image_decoder_callback.cpp", + "${services_path}/softbusadapter/src/softbus_adapter.cpp", + ] + + deps = [ + "${common_path}:distributed_screen_utils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensinktrans\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/services/screentransport/screensinktrans/include/iscreen_sink_trans.h b/services/screentransport/screensinktrans/include/iscreen_sink_trans.h new file mode 100644 index 00000000..ad0f3788 --- /dev/null +++ b/services/screentransport/screensinktrans/include/iscreen_sink_trans.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ISCREEN_SINK_TRANS_H +#define OHOS_ISCREEN_SINK_TRANS_H + +#include "surface.h" + +#include "iscreen_sink_trans_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class IScreenSinkTrans { +public: + virtual ~IScreenSinkTrans() = default; + + virtual int32_t SetUp(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) = 0; + virtual int32_t Release() = 0; + virtual int32_t Start() = 0; + virtual int32_t Stop() = 0; + virtual int32_t RegisterStateCallback(const std::shared_ptr &callBack) = 0; + virtual int32_t SetImageSurface(const sptr &surface) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinktrans/include/iscreen_sink_trans_callback.h b/services/screentransport/screensinktrans/include/iscreen_sink_trans_callback.h new file mode 100644 index 00000000..81a39a49 --- /dev/null +++ b/services/screentransport/screensinktrans/include/iscreen_sink_trans_callback.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ISCREEN_SINK_TRANS_CALLBACK_H +#define OHOS_ISCREEN_SINK_TRANS_CALLBACK_H + +#include + +namespace OHOS { +namespace DistributedHardware { +class IScreenSinkTransCallback { +public: + virtual ~IScreenSinkTransCallback() = default; + + virtual void OnError(int32_t err, const std::string &content) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinktrans/include/screen_sink_trans.h b/services/screentransport/screensinktrans/include/screen_sink_trans.h new file mode 100644 index 00000000..abd9e75a --- /dev/null +++ b/services/screentransport/screensinktrans/include/screen_sink_trans.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_SINK_TRANS_H +#define OHOS_SCREEN_SINK_TRANS_H + +#include +#include + +#include "iscreen_sink_trans.h" +#include "iscreen_sink_trans_callback.h" +#include "iimage_sink_processor.h" +#include "iscreen_channel.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenSinkTrans : public IScreenSinkTrans, + public IScreenChannelListener, + public IImageSinkProcessorListener, + public std::enable_shared_from_this { +public: + ScreenSinkTrans() = default; + ~ScreenSinkTrans() = default; + + int32_t SetUp(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId) override; + int32_t Release() override; + int32_t Start() override; + int32_t Stop() override; + int32_t RegisterStateCallback(const std::shared_ptr &callBack) override; + int32_t SetImageSurface(const sptr &surface) override; + + void OnSessionOpened() override; + void OnSessionClosed() override; + void OnDataReceived(const std::shared_ptr &data) override; + void OnProcessorStateNotify(int32_t state) override; + +private: + int32_t CheckVideoParam(const VideoParam ¶m); + int32_t CheckTransParam(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId); + int32_t InitScreenTrans(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId); + int32_t RegisterChannelListner(); + int32_t RegisterProcessorListner(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId); + +private: + static const constexpr char *LOG_TAG = "ScreenSinkTrans"; + + sptr decoderSurface_; + std::shared_ptr imageProcessor_; + std::shared_ptr screenChannel_; + std::weak_ptr transCallback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensinktrans/src/screen_sink_trans.cpp b/services/screentransport/screensinktrans/src/screen_sink_trans.cpp new file mode 100644 index 00000000..83b10eee --- /dev/null +++ b/services/screentransport/screensinktrans/src/screen_sink_trans.cpp @@ -0,0 +1,309 @@ +/* + * 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 "screen_sink_trans.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "image_sink_processor.h" +#include "screen_data_channel_impl.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ScreenSinkTrans::SetUp(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + DHLOGI("%s: SetUp.", LOG_TAG); + int32_t ret = CheckTransParam(localParam, remoteParam, peerDevId); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetUp failed param error ret: %d.", LOG_TAG, ret); + return ret; + } + + ret = InitScreenTrans(localParam, remoteParam, peerDevId); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetUp failed ret: %d.", LOG_TAG, ret); + return ret; + } + + DHLOGI("%s: SetUp success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::Release() +{ + DHLOGI("%s: Release.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageProcessor_->ReleaseImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Release image processor failed ret: %d.", LOG_TAG, ret); + } + imageProcessor_ = nullptr; + + ret = screenChannel_->ReleaseSession(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Release channel session failed ret: %d.", LOG_TAG, ret); + } + screenChannel_ = nullptr; + + DHLOGI("%s: Release success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::Start() +{ + DHLOGI("%s: Start.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageProcessor_->StartImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Start image processor failed ret: %d.", LOG_TAG, ret); + return ret; + } + + DHLOGI("%s: Start success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::Stop() +{ + DHLOGI("%s: Stop.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + bool stopStatus = true; + int32_t ret = imageProcessor_->StopImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Stop image processor failed ret: %d.", LOG_TAG, ret); + stopStatus = false; + } + + ret = screenChannel_->CloseSession(); + if (ret != DH_SUCCESS && ret != ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN) { + DHLOGD("%s: Close Session failed ret: %d.", LOG_TAG, ret); + stopStatus = false; + } + + if (!stopStatus) { + DHLOGE("%s: Stop sink trans failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ERROR; + } + + DHLOGI("%s: Stop success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::RegisterStateCallback(const std::shared_ptr &callback) +{ + DHLOGI("%s:RegisterStateCallback.", LOG_TAG); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + transCallback_ = callback; + + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::SetImageSurface(const sptr &surface) +{ + if (!surface) { + DHLOGE("%s: Image surface is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + decoderSurface_ = surface; + + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::CheckVideoParam(const VideoParam ¶m) +{ + if ((param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H264) && + (param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H265)) { + DHLOGE("%s: Invalid codec type.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetVideoFormat() != VIDEO_DATA_FORMAT_YUVI420) && + (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV12) && + (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV21)) { + DHLOGE("%s: Invalid video data format.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetVideoWidth() > DSCREEN_MAX_VIDEO_DATA_WIDTH) || + (param.GetVideoHeight() > DSCREEN_MAX_VIDEO_DATA_HEIGHT)) { + DHLOGE("%s: Invalid video data size.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetScreenWidth() > DSCREEN_MAX_SCREEN_DATA_WIDTH) || + (param.GetScreenHeight() > DSCREEN_MAX_SCREEN_DATA_HEIGHT)) { + DHLOGE("%s: Invalid screen data size.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::CheckTransParam(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + if (peerDevId.empty()) { + DHLOGE("%s: Remote device id is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = CheckVideoParam(localParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: check localParam param failed.", LOG_TAG); + return ret; + } + + ret = CheckVideoParam(remoteParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: check remoteParam param failed.", LOG_TAG); + return ret; + } + + DHLOGI("%s: Local: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, + localParam.GetCodecType(), localParam.GetVideoFormat(), localParam.GetVideoWidth(), + localParam.GetVideoHeight(), localParam.GetScreenWidth(), localParam.GetScreenHeight()); + DHLOGI("%s: Remote: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, + remoteParam.GetCodecType(), remoteParam.GetVideoFormat(), remoteParam.GetVideoWidth(), + remoteParam.GetVideoHeight(), remoteParam.GetScreenWidth(), remoteParam.GetScreenHeight()); + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::InitScreenTrans(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + screenChannel_ = std::make_shared(peerDevId); + if (!screenChannel_) { + DHLOGE("%s: Create screen data channel failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + int32_t ret = RegisterChannelListner(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register channel listener failed.", LOG_TAG); + screenChannel_ = nullptr; + return ret; + } + + imageProcessor_ = std::make_shared(); + if (!imageProcessor_) { + DHLOGE("%s: Create image processor failed.", LOG_TAG); + screenChannel_ = nullptr; + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + ret = RegisterProcessorListner(localParam, remoteParam, peerDevId); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register processor listener failed.", LOG_TAG); + screenChannel_ = nullptr; + imageProcessor_ = nullptr; + return ret; + } + + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::RegisterChannelListner() +{ + DHLOGI("%s: RegisterChannelListner.", LOG_TAG); + std::shared_ptr listener = shared_from_this(); + if (!listener) { + DHLOGE("%s: Channel Listener is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = screenChannel_->CreateSession(listener); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register channel listenner failed ret: %d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ScreenSinkTrans::RegisterProcessorListner(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + DHLOGI("%s: RegisterProcessorListner.", LOG_TAG); + std::shared_ptr listener = shared_from_this(); + if (!listener) { + DHLOGE("%s: Channel listener to null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageProcessor_->ConfigureImageProcessor(localParam, remoteParam, listener); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Config image processor failed ret: %d.", LOG_TAG, ret); + return ret; + } + + ret = imageProcessor_->SetImageSurface(decoderSurface_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Set image surface failed ret: %d.", LOG_TAG, ret); + return ret; + } + return DH_SUCCESS; +} + +void ScreenSinkTrans::OnSessionOpened() +{ + DHLOGI("%s: OnChannelSessionOpened.", LOG_TAG); +} + +void ScreenSinkTrans::OnSessionClosed() +{ + DHLOGI("%s:OnChannelSessionClosed.", LOG_TAG); + std::shared_ptr callback = transCallback_.lock(); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return; + } + callback->OnError(ERR_DH_SCREEN_TRANS_SESSION_CLOSED, "OnChannelSessionClosed"); +} + +void ScreenSinkTrans::OnDataReceived(const std::shared_ptr &data) +{ + DHLOGD("%s: OnChannelDataReceived.", LOG_TAG); + int32_t ret = imageProcessor_->ProcessImage(data); + if (ret != DH_SUCCESS) { + DHLOGE("%s: send data to image processor failed ret: %d.", LOG_TAG, ret); + } +} + +void ScreenSinkTrans::OnProcessorStateNotify(int32_t state) +{ + DHLOGI("%s: OnProcessorStateNotify.", LOG_TAG); + std::shared_ptr callback = transCallback_.lock(); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return; + } + callback->OnError(state, "OnProcessorStateNotify"); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/encoder/include/image_encoder_callback.h b/services/screentransport/screensourceprocessor/encoder/include/image_encoder_callback.h new file mode 100644 index 00000000..b3410caf --- /dev/null +++ b/services/screentransport/screensourceprocessor/encoder/include/image_encoder_callback.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 OHOS_IMAGE_ENCODER_CALLBACK_H +#define OHOS_IMAGE_ENCODER_CALLBACK_H + +#include + +#include "media_errors.h" +#include "avcodec_common.h" +#include "format.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSourceEncoder; +class ImageEncoderCallback : public Media::AVCodecCallback { +public: + explicit ImageEncoderCallback(const std::shared_ptr &encoder) + : videoEncoder_(encoder) {}; + ~ImageEncoderCallback() = default; + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode) override; + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag) override; + void OnInputBufferAvailable(uint32_t index) override; + void OnOutputFormatChanged(const Media::Format &format) override; + +private: + static const constexpr char *LOG_TAG = "ImageEncoderCallback"; + + std::weak_ptr videoEncoder_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h b/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h new file mode 100644 index 00000000..bcf6fa55 --- /dev/null +++ b/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IMAGE_SOURCE_ENCODER_H +#define OHOS_IMAGE_SOURCE_ENCODER_H + +#include + +#include "avsharedmemory.h" +#include "avcodec_video_encoder.h" +#include "avcodec_common.h" +#include "media_errors.h" +#include "format.h" +#include "surface.h" + +#include "iimage_source_processor_listener.h" +#include "image_encoder_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSourceEncoder : public std::enable_shared_from_this { +public: + explicit ImageSourceEncoder(const std::shared_ptr &imageListener) + : imageProcessorListener_(imageListener) {}; + ~ImageSourceEncoder() = default; + + int32_t ConfigureEncoder(const VideoParam &cofigParam); + int32_t ReleaseEncoder(); + int32_t StartEncoder(); + int32_t StopEncoder(); + sptr &GetInputSurface() + { + return videoSurface_; + } + + void OnError(Media::AVCodecErrorType errorType, int32_t errorCode); + void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag); + void OnInputBufferAvailable(uint32_t index); + void OnOutputFormatChanged(const Media::Format &format); + +private: + int32_t InitVideoEncoder(const VideoParam &configParam); + int32_t SetEncoderFormat(const VideoParam &cofigParam); + +private: + static const constexpr char *LOG_TAG = "ImageSourceEncoder"; + + Media::Format imageFormat_; + Media::AVCodecBufferInfo encoderBufferInfo_; + + sptr videoSurface_; + std::shared_ptr videoEncoder_; + std::shared_ptr videoSharedMemory_; + std::shared_ptr encodeVideoCallback_; + std::weak_ptr imageProcessorListener_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/encoder/src/image_encoder_callback.cpp b/services/screentransport/screensourceprocessor/encoder/src/image_encoder_callback.cpp new file mode 100644 index 00000000..2cfe9ff9 --- /dev/null +++ b/services/screentransport/screensourceprocessor/encoder/src/image_encoder_callback.cpp @@ -0,0 +1,68 @@ +/* + * 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 "image_encoder_callback.h" + +#include "dscreen_log.h" +#include "image_source_encoder.h" + +namespace OHOS { +namespace DistributedHardware { +void ImageEncoderCallback::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGD("%s: OnError.", LOG_TAG); + std::shared_ptr encoder = videoEncoder_.lock(); + if (encoder == nullptr) { + DHLOGE("encoder is nullptr."); + return; + } + encoder->OnError(errorType, errorCode); +} + +void ImageEncoderCallback::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGD("%s: OnOutputBufferAvailable.", LOG_TAG); + std::shared_ptr encoder = videoEncoder_.lock(); + if (encoder == nullptr) { + DHLOGE("encoder is nullptr."); + return; + } + encoder->OnOutputBufferAvailable(index, info, flag); +} + +void ImageEncoderCallback::OnInputBufferAvailable(uint32_t index) +{ + DHLOGD("%s: OnInputBufferAvailable.", LOG_TAG); + std::shared_ptr encoder = videoEncoder_.lock(); + if (encoder == nullptr) { + DHLOGE("encoder is nullptr."); + return; + } + encoder->OnInputBufferAvailable(index); +} + +void ImageEncoderCallback::OnOutputFormatChanged(const Media::Format &format) +{ + DHLOGD("%s: OnOutputFormatChanged.", LOG_TAG); + std::shared_ptr encoder = videoEncoder_.lock(); + if (encoder == nullptr) { + DHLOGE("encoder is nullptr."); + return; + } + encoder->OnOutputFormatChanged(format); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp b/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp new file mode 100644 index 00000000..4fb31b4b --- /dev/null +++ b/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp @@ -0,0 +1,250 @@ +/* + * 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 "image_source_encoder.h" + +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ImageSourceEncoder::ConfigureEncoder(const VideoParam &configParam) +{ + DHLOGI("%s: ConfigureEncoder.", LOG_TAG); + int32_t ret = InitVideoEncoder(configParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Init encoder failed ret:%d.", LOG_TAG, ret); + return ret; + } + + ret = SetEncoderFormat(configParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Set encoder format failed ret:%d.", LOG_TAG, ret); + return ret; + } + + videoSurface_ = videoEncoder_->CreateInputSurface(); + if (videoSurface_ == nullptr) { + DHLOGE("%s: Create encoder surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceEncoder::ReleaseEncoder() +{ + DHLOGI("%s: ReleaseEncoder.", LOG_TAG); + if (!videoEncoder_) { + DHLOGE("%s: Encoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoEncoder_->Release(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Release encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_RELEASE_FAILED; + } + encodeVideoCallback_ = nullptr; + videoEncoder_ = nullptr; + + return DH_SUCCESS; +} + +int32_t ImageSourceEncoder::StartEncoder() +{ + DHLOGI("%s: StartEncoder.", LOG_TAG); + if (!videoEncoder_) { + DHLOGE("%s: Encoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoEncoder_->Prepare(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Prepare encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_PREPARE_FAILED; + } + + ret = videoEncoder_->Start(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Start encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_START_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceEncoder::StopEncoder() +{ + DHLOGI("%s: StopEncoder.", LOG_TAG); + if (!videoEncoder_) { + DHLOGE("%s: Encoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = videoEncoder_->Flush(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Flush encoder failed.", LOG_TAG); + } + + ret = videoEncoder_->Stop(); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Stop encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_STOP_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceEncoder::InitVideoEncoder(const VideoParam &configParam) +{ + DHLOGI("%s: InitVideoEncoder.", LOG_TAG); + switch (configParam.GetCodecType()) { + case VIDEO_CODEC_TYPE_VIDEO_H264: + videoEncoder_ = Media::VideoEncoderFactory::CreateByName("OMX_hisi_video_encoder_avc"); + break; + case VIDEO_CODEC_TYPE_VIDEO_H265: + videoEncoder_ = Media::VideoEncoderFactory::CreateByMime("video/hevc"); + break; + default: + DHLOGE("%s: codecType is invalid!", LOG_TAG); + videoEncoder_ = nullptr; + } + + if (videoEncoder_ == nullptr) { + DHLOGE("%s: Create videoEncoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_CREATE_CODEC_FAILED; + } + + encodeVideoCallback_ = std::make_shared(shared_from_this()); + int32_t ret = videoEncoder_->SetCallback(encodeVideoCallback_); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Set codec callback failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SET_CALLBACK_FAILED; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceEncoder::SetEncoderFormat(const VideoParam &configParam) +{ + DHLOGI("%s: SetEncoderFormat.", LOG_TAG); + if (!videoEncoder_) { + DHLOGE("%s: Encoder is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + switch (configParam.GetCodecType()) { + case VIDEO_CODEC_TYPE_VIDEO_H264: + imageFormat_.PutStringValue("codec_mime", "video/avc"); + break; + case VIDEO_CODEC_TYPE_VIDEO_H265: + imageFormat_.PutStringValue("codec_mime", "video/hevc"); + break; + default: + DHLOGE("%s: Codec type is invalid.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + switch (configParam.GetVideoFormat()) { + case VIDEO_DATA_FORMAT_YUVI420: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::YUVI420); + break; + case VIDEO_DATA_FORMAT_NV12: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12); + break; + case VIDEO_DATA_FORMAT_NV21: + imageFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV21); + break; + default: + DHLOGE("%s: Video format is invalid.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + imageFormat_.PutLongValue("max_input_size", MAX_YUV420_BUFFER_SIZE); + imageFormat_.PutIntValue("width", configParam.GetVideoWidth()); + imageFormat_.PutIntValue("height", configParam.GetVideoHeight()); + imageFormat_.PutIntValue("frame_rate", configParam.GetFps()); + + int32_t ret = videoEncoder_->Configure(imageFormat_); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: Configure encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_CONFIGURE_FAILED; + } + return DH_SUCCESS; +} + +void ImageSourceEncoder::OnError(Media::AVCodecErrorType errorType, int32_t errorCode) +{ + DHLOGI("%s: Encoder error, errorType(%d), errorCode(%d)", LOG_TAG, errorType, errorCode); + std::shared_ptr listener = imageProcessorListener_.lock(); + if (!listener) { + DHLOGE("%s: Processor listener is null", LOG_TAG); + return; + } + listener->OnProcessorStateNotify(errorCode); +} + +void ImageSourceEncoder::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, + Media::AVCodecBufferFlag flag) +{ + DHLOGD("%s: OnOutputBufferAvailable.", LOG_TAG); + std::shared_ptr listener = imageProcessorListener_.lock(); + if (!listener) { + DHLOGE("%s: Processor listener is null", LOG_TAG); + return; + } + if (!videoEncoder_) { + DHLOGE("%s: Encoder is null.", LOG_TAG); + return; + } + + encoderBufferInfo_ = info; + videoSharedMemory_ = videoEncoder_->GetOutputBuffer(index); + if (!videoSharedMemory_) { + DHLOGE("%s: GetOutputBuffer failed.", LOG_TAG); + return; + } + + size_t dataSize = static_cast(info.size); + auto dataBuf = std::make_shared(dataSize); + if (!dataBuf) { + DHLOGE("%s: Create buffer failed.", LOG_TAG); + } + int32_t ret = memcpy_s(dataBuf->Data(), dataBuf->Capacity(), videoSharedMemory_->GetBase(), dataSize); + if (ret != EOK) { + DHLOGE("%s: Copy data failed.", LOG_TAG); + return; + } + listener->OnImageProcessDone(dataBuf); + + ret = videoEncoder_->ReleaseOutputBuffer(index); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: videoEncoder ReleaseOutputBuffer failed.", LOG_TAG); + } +} + +void ImageSourceEncoder::OnInputBufferAvailable(uint32_t index) +{ + (void) index; +} + +void ImageSourceEncoder::OnOutputFormatChanged(const Media::Format &format) +{ + (void) format; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/include/iimage_source_processor.h b/services/screentransport/screensourceprocessor/include/iimage_source_processor.h new file mode 100644 index 00000000..06dad68e --- /dev/null +++ b/services/screentransport/screensourceprocessor/include/iimage_source_processor.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IIMAGE_SOURCE_PROCESSOR_H +#define OHOS_IIMAGE_SOURCE_PROCESSOR_H + +#include "surface.h" + +#include + +#include "data_buffer.h" +#include "iimage_source_processor_listener.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class IImageSourceProcessor { +public: + virtual ~IImageSourceProcessor() = default; + + virtual int32_t ConfigureImageProcessor(const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &listener) = 0; + virtual int32_t ReleaseImageProcessor() = 0; + virtual int32_t StartImageProcessor() = 0; + virtual int32_t StopImageProcessor() = 0; + virtual sptr &GetImageSurface() = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h b/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h new file mode 100644 index 00000000..eab3f25a --- /dev/null +++ b/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IIMAGE_SOURCE_PROCESSOR_LISTENER_H +#define OHOS_IIMAGE_SOURCE_PROCESSOR_LISTENER_H + +#include "data_buffer.h" + +namespace OHOS { +namespace DistributedHardware { +class IImageSourceProcessorListener { +public: + virtual ~IImageSourceProcessorListener() = default; + + virtual void OnImageProcessDone(const std::shared_ptr &data) = 0; + virtual void OnProcessorStateNotify(int32_t state) = 0; +}; +} // namespace DistributedHardware +} // namsspace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/include/image_source_processor.h b/services/screentransport/screensourceprocessor/include/image_source_processor.h new file mode 100644 index 00000000..b95f9c14 --- /dev/null +++ b/services/screentransport/screensourceprocessor/include/image_source_processor.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 OHOS_IMAGE_SOURCE_PROCESSOR_H +#define OHOS_IMAGE_SOURCE_PROCESSOR_H + +#include "iimage_source_processor.h" +#include "iimage_source_processor_listener.h" +#include "image_source_encoder.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSourceProcessor : public IImageSourceProcessor { +public: + ImageSourceProcessor() = default; + ~ImageSourceProcessor() = default; + + int32_t ConfigureImageProcessor(const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &listener) override; + int32_t ReleaseImageProcessor() override; + int32_t StartImageProcessor() override; + int32_t StopImageProcessor() override; + sptr &GetImageSurface() override; + +private: + static const constexpr char *LOG_TAG = "ImageSourceProcessor"; + VideoParam localParam_; + VideoParam remoteParam_; + std::shared_ptr imageEncoder_ = nullptr; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/src/image_source_processor.cpp b/services/screentransport/screensourceprocessor/src/image_source_processor.cpp new file mode 100644 index 00000000..68e74783 --- /dev/null +++ b/services/screentransport/screensourceprocessor/src/image_source_processor.cpp @@ -0,0 +1,101 @@ +/* + * 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 "image_source_processor.h" + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ImageSourceProcessor::ConfigureImageProcessor(const VideoParam &localParam, const VideoParam &remoteParam, + const std::shared_ptr &listener) +{ + DHLOGI("%s: ConfigureImageProcessor.", LOG_TAG); + imageEncoder_ = std::make_shared(listener); + if (!imageEncoder_) { + DHLOGE("%s: Create screen encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageEncoder_->ConfigureEncoder(localParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Configure screen encoder failed ret: %d.", LOG_TAG, ret); + return ret; + } + + localParam_ = localParam; + remoteParam_ = remoteParam; + return DH_SUCCESS; +} + +int32_t ImageSourceProcessor::ReleaseImageProcessor() +{ + DHLOGI("%s: ReleaseImageProcessor.", LOG_TAG); + if (!imageEncoder_) { + DHLOGE("%s: Create screen encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageEncoder_->ReleaseEncoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Release screen encoder failed ret: %d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceProcessor::StartImageProcessor() +{ + DHLOGI("%s: StartImageProcessor.", LOG_TAG); + if (!imageEncoder_) { + DHLOGE("%s: Create screen encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageEncoder_->StartEncoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Start screen encoder failed ret: %d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ImageSourceProcessor::StopImageProcessor() +{ + DHLOGI("%s: StopImageProcessor.", LOG_TAG); + if (!imageEncoder_) { + DHLOGE("%s: Create screen encoder failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageEncoder_->StopEncoder(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Stop screen encoder failed ret: %d.", LOG_TAG, ret); + return ret; + } + + return DH_SUCCESS; +} + +sptr &ImageSourceProcessor::GetImageSurface() +{ + DHLOGI("%s: GetImageSurface.", LOG_TAG); + return imageEncoder_->GetInputSurface(); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/BUILD.gn b/services/screentransport/screensourcetrans/BUILD.gn new file mode 100644 index 00000000..09e5afa1 --- /dev/null +++ b/services/screentransport/screensourcetrans/BUILD.gn @@ -0,0 +1,69 @@ +# 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. + +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +ohos_shared_library("distributed_screen_sourcetrans") { + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/softbusadapter/include", + ] + + sources = [ + "./src/screen_source_trans.cpp", + "${services_path}/common/databuffer/src/data_buffer.cpp", + "${services_path}/common/utils/src/video_param.cpp", + "${services_path}/screentransport/screendatachannel/src/screen_data_channel_impl.cpp", + "${services_path}/screentransport/screensourceprocessor/src/image_source_processor.cpp", + "${services_path}/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp", + "${services_path}/screentransport/screensourceprocessor/encoder/src/image_encoder_callback.cpp", + "${services_path}/softbusadapter/src/softbus_adapter.cpp", + ] + + deps = [ + "${common_path}:distributed_screen_utils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"dscreensourcetrans\"", + "LOG_DOMAIN=0xD004100", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_screen" +} \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/include/iscreen_source_trans.h b/services/screentransport/screensourcetrans/include/iscreen_source_trans.h new file mode 100644 index 00000000..2b3c8e7f --- /dev/null +++ b/services/screentransport/screensourcetrans/include/iscreen_source_trans.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ISCREEN_SOURCE_TRANS_H +#define OHOS_ISCREEN_SOURCE_TRANS_H + +#include "surface.h" + +#include "iscreen_source_trans_callback.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class IScreenSourceTrans { +public: + virtual ~IScreenSourceTrans() = default; + + virtual int32_t SetUp(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) = 0; + virtual int32_t Release() = 0; + virtual int32_t Start() = 0; + virtual int32_t Stop() = 0; + virtual int32_t RegisterStateCallback(const std::shared_ptr &callBack) = 0; + virtual sptr &GetImageSurface() = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/include/iscreen_source_trans_callback.h b/services/screentransport/screensourcetrans/include/iscreen_source_trans_callback.h new file mode 100644 index 00000000..fafba69a --- /dev/null +++ b/services/screentransport/screensourcetrans/include/iscreen_source_trans_callback.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ISCREEN_SOURCE_TRANS_CALLBACK_H +#define OHOS_ISCREEN_SOURCE_TRANS_CALLBACK_H + +#include + +namespace OHOS { +namespace DistributedHardware { +class IScreenSourceTransCallback { +public: + virtual ~IScreenSourceTransCallback() = default; + + virtual void OnError(int32_t err, const std::string &content) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/include/screen_source_trans.h b/services/screentransport/screensourcetrans/include/screen_source_trans.h new file mode 100644 index 00000000..b513c739 --- /dev/null +++ b/services/screentransport/screensourcetrans/include/screen_source_trans.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_SOURCE_TRANS_H +#define OHOS_SCREEN_SOURCE_TRANS_H + +#include +#include +#include +#include +#include +#include + +#include "iimage_source_processor.h" +#include "iscreen_source_trans.h" +#include "iscreen_source_trans_callback.h" +#include "iscreen_channel.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenSourceTrans : public IScreenSourceTrans, + public IScreenChannelListener, + public IImageSourceProcessorListener, + public std::enable_shared_from_this { +public: + ScreenSourceTrans() = default; + ~ScreenSourceTrans() = default; + + int32_t SetUp(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId) override; + int32_t Release() override; + int32_t Start() override; + int32_t Stop() override; + int32_t RegisterStateCallback(const std::shared_ptr &callBack) override; + sptr &GetImageSurface() override; + + void OnSessionOpened() override; + void OnSessionClosed() override; + void OnDataReceived(const std::shared_ptr &data) override; + void OnImageProcessDone(const std::shared_ptr &data) override; + void OnProcessorStateNotify(int32_t state) override; + +private: + int32_t CheckVideoParam(const VideoParam ¶m); + int32_t CheckTransParam(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId); + int32_t InitScreenTrans(const VideoParam &localParam, const VideoParam &remoteParam, const std::string &peerDevId); + int32_t RegisterChannelListner(); + int32_t RegisterProcessorListner(const VideoParam &localParam, const VideoParam &remoteParam); + void FeedChannelData(); + +private: + static const constexpr char *LOG_TAG = "ScreenSourceTrans"; + static constexpr uint8_t SESSION_WAIT_SECONDS = 5; + static constexpr uint8_t DATA_WAIT_SECONDS = 1; + static constexpr size_t DATA_QUEUE_MAX_SIZE = 10; + + std::mutex sessionMtx_; + std::mutex dataMtx_; + std::condition_variable sessionCond_; + std::condition_variable dataCond_; + std::mutex dataQueueMtx_; + std::thread sendDataThread_; + + bool isChannelReady_ = false; + sptr encoderSurface_; + std::queue> dataQueue_; + + std::shared_ptr imageProcessor_; + std::shared_ptr screenChannel_; + std::weak_ptr transCallback_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/src/screen_source_trans.cpp b/services/screentransport/screensourcetrans/src/screen_source_trans.cpp new file mode 100644 index 00000000..13faed9b --- /dev/null +++ b/services/screentransport/screensourcetrans/src/screen_source_trans.cpp @@ -0,0 +1,382 @@ +/* + * 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 "screen_source_trans.h" + +#include + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "image_source_processor.h" +#include "screen_data_channel_impl.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t ScreenSourceTrans::SetUp(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + DHLOGI("%s: SetUp.", LOG_TAG); + int32_t ret = CheckTransParam(localParam, remoteParam, peerDevId); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetUp failed param error ret: %d.", LOG_TAG, ret); + return ret; + } + + ret = InitScreenTrans(localParam, remoteParam, peerDevId); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SetUp failed ret: %d.", LOG_TAG, ret); + return ret; + } + + DHLOGI("%s: SetUp success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::Release() +{ + DHLOGI("%s: Release.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = imageProcessor_->ReleaseImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Release image processor failed ret: %d.", LOG_TAG, ret); + } + imageProcessor_ = nullptr; + + ret = screenChannel_->ReleaseSession(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Release channel session failed ret: %d.", LOG_TAG, ret); + } + screenChannel_ = nullptr; + + std::lock_guard lck(dataQueueMtx_); + while (!dataQueue_.empty()) { + dataQueue_.pop(); + } + + DHLOGI("%s: Release success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::Start() +{ + DHLOGI("%s: Start.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = screenChannel_->OpenSession(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Open channel session failed ret: %d.", LOG_TAG, ret); + return ret; + } + + DHLOGI("%s: Wait for channel session opened.", LOG_TAG); + std::unique_lock lck(sessionMtx_); + auto status = + sessionCond_.wait_for(lck, std::chrono::seconds(SESSION_WAIT_SECONDS), [this]() { return isChannelReady_; }); + if (!status) { + DHLOGE("%s: Open channel session timeout(%ds).", LOG_TAG, SESSION_WAIT_SECONDS); + return ERR_DH_SCREEN_TRANS_TIMEOUT; + } + + DHLOGI("%s: Start success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::Stop() +{ + DHLOGI("%s: Stop.", LOG_TAG); + if (!imageProcessor_ || !screenChannel_) { + DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + bool stopStatus = true; + int32_t ret = imageProcessor_->StopImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Stop image processor failed ret: %d.", LOG_TAG, ret); + stopStatus = false; + } + + ret = screenChannel_->CloseSession(); + if (ret != DH_SUCCESS) { + DHLOGD("%s: Close Session failed ret: %d.", LOG_TAG, ret); + stopStatus = false; + } + isChannelReady_ = false; + sendDataThread_.join(); + + if (!stopStatus) { + DHLOGE("%s: Stop source trans failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ERROR; + } + DHLOGI("%s: Stop success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::RegisterStateCallback(const std::shared_ptr &callback) +{ + DHLOGI("%s:RegisterStateCallback.", LOG_TAG); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + transCallback_ = callback; + + return DH_SUCCESS; +} + +sptr &ScreenSourceTrans::GetImageSurface() +{ + DHLOGI("%s:GetImageSurface.", LOG_TAG); + return encoderSurface_; +} + +int32_t ScreenSourceTrans::CheckVideoParam(const VideoParam ¶m) +{ + if ((param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H264) && + (param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H265)) { + DHLOGE("%s: Invalid codec type.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetVideoFormat() != VIDEO_DATA_FORMAT_YUVI420) && + (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV12) && + (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV21)) { + DHLOGE("%s: Invalid video data format.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetVideoWidth() > DSCREEN_MAX_VIDEO_DATA_WIDTH) || + (param.GetVideoHeight() > DSCREEN_MAX_VIDEO_DATA_HEIGHT)) { + DHLOGE("%s: Invalid video data size.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + if ((param.GetScreenWidth() > DSCREEN_MAX_SCREEN_DATA_WIDTH) || + (param.GetScreenHeight() > DSCREEN_MAX_SCREEN_DATA_HEIGHT)) { + DHLOGE("%s: Invalid screen data size.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM; + } + + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::CheckTransParam(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + if (peerDevId.empty()) { + DHLOGE("%s: Remote device id is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + int32_t ret = CheckVideoParam(localParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: check localParam param failed.", LOG_TAG); + return ret; + } + + ret = CheckVideoParam(remoteParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: check remoteParam param failed.", LOG_TAG); + return ret; + } + + DHLOGI("%s: Local: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, + localParam.GetCodecType(), localParam.GetVideoFormat(), localParam.GetVideoWidth(), + localParam.GetVideoHeight(), localParam.GetScreenWidth(), localParam.GetScreenHeight()); + DHLOGI("%s: Remote: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, + remoteParam.GetCodecType(), remoteParam.GetVideoFormat(), remoteParam.GetVideoWidth(), + remoteParam.GetVideoHeight(), remoteParam.GetScreenWidth(), remoteParam.GetScreenHeight()); + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::InitScreenTrans(const VideoParam &localParam, const VideoParam &remoteParam, + const std::string &peerDevId) +{ + screenChannel_ = std::make_shared(peerDevId); + if (!screenChannel_) { + DHLOGE("%s: Create screen data channel failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + int32_t ret = RegisterChannelListner(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register channel listener failed ret: %d.", LOG_TAG, ret); + screenChannel_ = nullptr; + return ret; + } + + imageProcessor_ = std::make_shared(); + if (!imageProcessor_) { + DHLOGE("%s: Create image processor failed.", LOG_TAG); + screenChannel_ = nullptr; + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + ret = RegisterProcessorListner(localParam, remoteParam); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register data processor listener failed ret: %d.", LOG_TAG, ret); + screenChannel_ = nullptr; + imageProcessor_ = nullptr; + return ret; + } + + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::RegisterChannelListner() +{ + DHLOGI("%s: RegisterChannelListner.", LOG_TAG); + std::shared_ptr listener = shared_from_this(); + if (!listener) { + DHLOGE("%s: Channel listener is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + if (screenChannel_ == nullptr) { + DHLOGE("%s: Channel is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + int32_t ret = screenChannel_->CreateSession(listener); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Create session failed ret: %d.", LOG_TAG); + return ret; + } + + return DH_SUCCESS; +} + +int32_t ScreenSourceTrans::RegisterProcessorListner(const VideoParam &localParam, const VideoParam &remoteParam) +{ + DHLOGI("%s: RegisterProcessorListner.", LOG_TAG); + std::shared_ptr listener = shared_from_this(); + if (!listener) { + DHLOGE("%s: Processor listener is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ERROR; + } + + int32_t ret = imageProcessor_->ConfigureImageProcessor(localParam, remoteParam, listener); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Config image processor failed ret: %d.", LOG_TAG, ret); + return ret; + } + + encoderSurface_ = imageProcessor_->GetImageSurface(); + if (!encoderSurface_) { + DHLOGE("%s: Surface is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + + return DH_SUCCESS; +} + +void ScreenSourceTrans::OnSessionOpened() +{ + DHLOGI("%s: OnChannelSessionOpened.", LOG_TAG); + int32_t ret = imageProcessor_->StartImageProcessor(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Start image processor failed ret: %d.", LOG_TAG, ret); + return; + } + + isChannelReady_ = true; + DHLOGI("%s: Start thread.", LOG_TAG); + sendDataThread_ = std::thread(&ScreenSourceTrans::FeedChannelData, this); + + std::unique_lock lck(sessionMtx_); + sessionCond_.notify_all(); +} + +void ScreenSourceTrans::OnSessionClosed() +{ + DHLOGI("%s: OnChannelSessionClosed.", LOG_TAG); + isChannelReady_ = false; + sendDataThread_.join(); + + std::shared_ptr callback = transCallback_.lock(); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return; + } + callback->OnError(ERR_DH_SCREEN_TRANS_SESSION_CLOSED, "OnChannelSessionClosed"); +} + +void ScreenSourceTrans::OnDataReceived(const std::shared_ptr &data) +{ + (void) data; + DHLOGI("%s: OnChannelDataReceived source trans not support.", LOG_TAG); +} + +void ScreenSourceTrans::OnImageProcessDone(const std::shared_ptr &data) +{ + DHLOGD("%s: OnProcessorDataReceived received data from data processor.", LOG_TAG); + std::lock_guard lck(dataQueueMtx_); + while (dataQueue_.size() >= DATA_QUEUE_MAX_SIZE) { + DHLOGE("%s: Data queue overflow.", LOG_TAG); + dataQueue_.pop(); + } + dataQueue_.push(data); + dataCond_.notify_all(); +} + +void ScreenSourceTrans::OnProcessorStateNotify(int32_t state) +{ + DHLOGI("%s:OnProcessorStateNotify.", LOG_TAG); + std::shared_ptr callback = transCallback_.lock(); + if (!callback) { + DHLOGE("%s: Trans callback is null.", LOG_TAG); + return; + } + callback->OnError(state, "OnProcessorStateNotify"); +} + +void ScreenSourceTrans::FeedChannelData() +{ + while (isChannelReady_) { + std::shared_ptr screenData; + { + std::unique_lock lock(dataQueueMtx_); + dataCond_.wait_for(lock, std::chrono::seconds(DATA_WAIT_SECONDS), [this]() { return !dataQueue_.empty(); }); + if (dataQueue_.empty()) { + DHLOGD("%s:Data queue is empty.", LOG_TAG); + continue; + } + screenData = dataQueue_.front(); + dataQueue_.pop(); + } + + if (screenChannel_ == nullptr) { + DHLOGE("%s: Channel is null", LOG_TAG); + return; + } + if (screenData == nullptr) { + DHLOGE("%s: Screen data is null", LOG_TAG); + continue; + } + + DHLOGD("%s: FeedChannelData.", LOG_TAG); + int32_t ret = screenChannel_->SendData(screenData); + if (ret != DH_SUCCESS) { + DHLOGD("%s:Send data failed.", LOG_TAG); + } + DHLOGD("%s: FeedChannelData success.", LOG_TAG); + } +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/test/unittest/BUILD.gn b/services/screentransport/test/unittest/BUILD.gn new file mode 100644 index 00000000..4a59c82f --- /dev/null +++ b/services/screentransport/test/unittest/BUILD.gn @@ -0,0 +1,23 @@ +# 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. + +group("screen_transport_test") { + testonly = true + deps = [ + "screensinktrans:sink_trans_test", + "screensinkprocessor:sink_processor_test", + "screensourcetrans:source_trans_test", + "screensourceprocessor:source_processor_test", + "screendatachannel:data_channel_test", + ] +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screendatachannel/BUILD.gn b/services/screentransport/test/unittest/screendatachannel/BUILD.gn new file mode 100644 index 00000000..da29a56d --- /dev/null +++ b/services/screentransport/test/unittest/screendatachannel/BUILD.gn @@ -0,0 +1,82 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/data_channel_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/softbusadapter/include", + ] +} + +## UnitTest screen_data_channel_test +ohos_unittest("DataChannelTest") { + module_out_path = module_out_path + + sources = [ "${services_path}/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"datachanneltest\"", + "LOG_DOMAIN=0xD004100", + ] + + cflags = [ "-frtti", + "-fexceptions" + ] + cflags_cc = cflags +} + +group("data_channel_test") { + testonly = true + deps = [ ":DataChannelTest" ] +} diff --git a/services/screentransport/test/unittest/screendatachannel/include/screen_data_channel_impl_test.h b/services/screentransport/test/unittest/screendatachannel/include/screen_data_channel_impl_test.h new file mode 100644 index 00000000..f5c34dbb --- /dev/null +++ b/services/screentransport/test/unittest/screendatachannel/include/screen_data_channel_impl_test.h @@ -0,0 +1,39 @@ +/* + * 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 +#include +#include + +#include "softbus_common.h" +#include "softbus_bus_center.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "screen_data_channel_impl.h" +#include "screentrans_test_utils.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenDataChannelImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + std::shared_ptr dataChannelImpl_ = nullptr; +}; +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp b/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp new file mode 100644 index 00000000..2b103279 --- /dev/null +++ b/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp @@ -0,0 +1,203 @@ +/* + * 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 private public +#include "screen_data_channel_impl_test.h" +#undef private + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ScreenDataChannelImplTest::SetUpTestCase(void) {} + +void ScreenDataChannelImplTest::TearDownTestCase(void) {} + +void ScreenDataChannelImplTest::SetUp(void) +{ + std::string peerDevId = "test"; + dataChannelImpl_ = std::make_shared(peerDevId); +} + +void ScreenDataChannelImplTest::TearDown(void) {} + +/** + * @tc.name: CreateSession_001 + * @tc.desc: Verify the CreateSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, CreateSession_001, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + int32_t ret = dataChannelImpl_->CreateSession(listener); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, ret); +} + +/** + * @tc.name: release_session_test_001 + * @tc.desc: Verify the ReleaseSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, release_session_test_001, TestSize.Level1) +{ + std::shared_ptr listener = + std::make_shared(); + + dataChannelImpl_->CreateSession(listener); + int32_t ret = dataChannelImpl_->ReleaseSession(); + EXPECT_EQ(DH_SUCCESS, ret); +} + +/** + * @tc.name: release_session_test_002 + * @tc.desc: Verify the ReleaseSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, release_session_test_002, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION, dataChannelImpl_->ReleaseSession()); +} + +/** + * @tc.name: close_session_test_001 + * @tc.desc: Verify the CloseSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, close_session_test_001, TestSize.Level1) +{ + dataChannelImpl_->sessionId_ = 1; + EXPECT_EQ(DH_SUCCESS, dataChannelImpl_->CloseSession()); +} + +/** + * @tc.name: close_session_test_002 + * @tc.desc: Verify the CloseSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, close_session_test_002, TestSize.Level1) +{ + dataChannelImpl_->sessionId_ = 0; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN, dataChannelImpl_->CloseSession()); +} + +/** + * @tc.name: send_data_test_002 + * @tc.desc: Verify the SendData function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, send_data_test_002, TestSize.Level1) +{ + std::shared_ptr data = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, dataChannelImpl_->SendData(data)); +} + +/** + * @tc.name: on_session_opened_test_001 + * @tc.desc: Verify the OnSessionOpened function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, on_session_opened_test_001, TestSize.Level1) +{ + std::shared_ptr listener = + std::make_shared(); + dataChannelImpl_->channelListener_ = listener; + int32_t sessionId = 0; + int32_t result = 0; + + dataChannelImpl_->OnSessionOpened(sessionId, result); +} + +/** + * @tc.name: on_session_opened_test_002 + * @tc.desc: Verify the OnSessionOpened function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, on_session_opened_test_002, TestSize.Level1) +{ + std::shared_ptr listener = + std::make_shared(); + dataChannelImpl_->channelListener_ = listener; + int32_t sessionId = -1; + int32_t result = -1; + + dataChannelImpl_->OnSessionOpened(sessionId, result); +} + +/** + * @tc.name: on_session_opened_test_003 + * @tc.desc: Verify the OnSessionOpened function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, on_session_opened_test_003, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + dataChannelImpl_->channelListener_ = listener; + int32_t sessionId = 0; + int32_t result = 0; + + dataChannelImpl_->OnSessionOpened(sessionId, result); +} + +/** + * @tc.name: on_session_closed_test_001 + * @tc.desc: Verify the OnSessionClosed function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, on_session_closed_test_001, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + dataChannelImpl_->channelListener_ = listener; + int32_t sessionId = 0; + + dataChannelImpl_->OnSessionClosed(sessionId); +} + +/** + * @tc.name: on_stream_received_test_001 + * @tc.desc: Verify the OnStreamReceived function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenDataChannelImplTest, on_stream_received_test_001, TestSize.Level1) +{ + std::shared_ptr listener = + std::make_shared(); + dataChannelImpl_->channelListener_ = listener; + + StreamData *ext = nullptr; + StreamFrameInfo *param = nullptr; + + int32_t sessionId = 0; + StreamData data; + data.buf = new char[DATA_LEN]; + data.bufLen = DATA_LEN; + + dataChannelImpl_->OnStreamReceived(sessionId, &data, ext, param); + delete[] data.buf; +} +} // DistributedHardware +} // OHOS \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn b/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn new file mode 100644 index 00000000..c61f8fb0 --- /dev/null +++ b/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn @@ -0,0 +1,86 @@ +# 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. + +import("//build/test.gni") +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/sink_processor_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/softbusadapter/include", + ] +} + +## UnitTest screen_sink_processor_test +ohos_unittest("SinkProcessorTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/screentransport/test/unittest/screensinkprocessor/src/image_sink_decoder_test.cpp", + "${services_path}/screentransport/test/unittest/screensinkprocessor/src/image_sink_processor_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensinktrans:distributed_screen_sinktrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"sinkprocessorest\"", + "LOG_DOMAIN=0xD004100", + ] + + remove_configs = [ "//build/config/compiler:no_rtti" ] + cflags = [ "-frtti" ] + cflags_cc = cflags +} + +group("sink_processor_test") { + testonly = true + deps = [ ":SinkProcessorTest" ] +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_decoder_test.h b/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_decoder_test.h new file mode 100644 index 00000000..4d6f2f3b --- /dev/null +++ b/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_decoder_test.h @@ -0,0 +1,42 @@ +/* + * 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 IMAGE_SINK_DECODER_TEST_H +#define IMAGE_SINK_DECODER_TEST_H + +#include + +#define private public +#include "image_sink_decoder.h" +#undef private +#include "iscreen_channel_listener.h" +#include "screentrans_test_utils.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSinkDecoderTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + VideoParam param_; + std::shared_ptr imageDecoder_ = nullptr; + std::shared_ptr imageListener_ = nullptr; +}; +} +} +#endif \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_processor_test.h b/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_processor_test.h new file mode 100644 index 00000000..b6db96db --- /dev/null +++ b/services/screentransport/test/unittest/screensinkprocessor/include/image_sink_processor_test.h @@ -0,0 +1,42 @@ +/* + * 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 IMAGE_SINK_DECODER_TEST_H +#define IMAGE_SINK_DECODER_TEST_H + +#include + +#define private public +#include "image_sink_processor.h" +#undef private +#include "screentrans_test_utils.h" +#include "iscreen_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +class ImageSinkProcessorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + VideoParam param_; + std::shared_ptr processor_; + std::shared_ptr imageListener_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_decoder_test.cpp b/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_decoder_test.cpp new file mode 100644 index 00000000..f1e9d5ea --- /dev/null +++ b/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_decoder_test.cpp @@ -0,0 +1,344 @@ +/* + * 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 "image_sink_decoder_test.h" + +#include +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ImageSinkDecoderTest::SetUpTestCase(void) {} + +void ImageSinkDecoderTest::TearDownTestCase(void) {} + +void ImageSinkDecoderTest::SetUp(void) +{ + param_.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + param_.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + param_.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + param_.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + param_.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + param_.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + param_.fps_ = FPS; + + imageListener_ = std::make_shared(); + imageDecoder_ = std::make_shared(imageListener_); + imageDecoder_->videoDecoder_ = Media::VideoDecoderFactory::CreateByMime("video/avc"); +} + +void ImageSinkDecoderTest::TearDown(void) {} + +/** + * @tc.name: configure_decoder_test_001 + * @tc.desc: Verify the ConfigureDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, configure_decoder_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, imageDecoder_->ConfigureDecoder(param_)); +} + +/** + * @tc.name: configure_decoder_test_002 + * @tc.desc: Verify the ConfigureDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, configure_decoder_test_002, TestSize.Level1) +{ + param_.codecType_ = VIDEO_CODEC_TYPE_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->ConfigureDecoder(param_)); +} + +/** + * @tc.name: release_decoder_test_001 + * @tc.desc: Verify the ReleaseDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, release_decoder_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, imageDecoder_->ReleaseDecoder()); +} + +/** + * @tc.name: release_decoder_test_002 + * @tc.desc: Verify the ReleaseDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, release_decoder_test_002, TestSize.Level1) +{ + imageDecoder_->videoDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->ReleaseDecoder()); +} + +/** + * @tc.name: start_decoder_test_001 + * @tc.desc: Verify the StartDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, start_decoder_test_001, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_CODEC_PREPARE_FAILED, imageDecoder_->StartDecoder()); +} + +/** + * @tc.name: start_decoder_test_002 + * @tc.desc: Verify the StartDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, start_decoder_test_002, TestSize.Level1) +{ + imageDecoder_->videoDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->StartDecoder()); +} + +/** + * @tc.name: stop_decoder_test_001 + * @tc.desc: Verify the StopDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, stop_decoder_test_001, TestSize.Level1) +{ + imageDecoder_->videoDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->StopDecoder()); +} + +/** + * @tc.name: init_video_decoder_test_001 + * @tc.desc: Verify the InitVideoDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, init_video_decoder_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, imageDecoder_->InitVideoDecoder(param_)); +} + +/** + * @tc.name: init_video_decoder_test_002 + * @tc.desc: Verify the InitVideoDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, init_video_decoder_test_002, TestSize.Level1) +{ + param_.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H265; + EXPECT_EQ(DH_SUCCESS, imageDecoder_->InitVideoDecoder(param_)); +} + +/** + * @tc.name: init_video_decoder_test_003 + * @tc.desc: Verify the InitVideoDecoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, init_video_decoder_test_003, TestSize.Level1) +{ + param_.codecType_ = VIDEO_CODEC_TYPE_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->InitVideoDecoder(param_)); +} + +/** + * @tc.name: set_decoder_format_test_001 + * @tc.desc: Verify the SetDecoderFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, set_decoder_format_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, imageDecoder_->SetDecoderFormat(param_)); +} + +/** + * @tc.name: set_decoder_format_test_002 + * @tc.desc: Verify the SetDecoderFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, set_decoder_format_test_002, TestSize.Level1) +{ + imageDecoder_->videoDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->SetDecoderFormat(param_)); +} + +/** + * @tc.name: set_decoder_format_test_003 + * @tc.desc: Verify the SetDecoderFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, set_decoder_format_test_003, TestSize.Level1) +{ + param_.codecType_ = VIDEO_CODEC_TYPE_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION, imageDecoder_->SetDecoderFormat(param_)); +} + +/** + * @tc.name: set_output_surface_test_001 + * @tc.desc: Verify the SetOutputSurface function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, set_output_surface_test_001, TestSize.Level1) +{ + sptr surface = Surface::CreateSurfaceAsConsumer("test"); + imageDecoder_->videoDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, imageDecoder_->SetOutputSurface(surface)); +} + +/** + * @tc.name: on_error_test_001 + * @tc.desc: Verify the OnError function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_error_test_001, TestSize.Level1) +{ + Media::AVCodecErrorType errorType = Media::AVCODEC_ERROR_EXTEND_START; + int32_t errorCode = DH_SUCCESS; + imageDecoder_->OnError(errorType, errorCode); +} + +/** + * @tc.name: on_error_test_002 + * @tc.desc: Verify the OnError function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_error_test_002, TestSize.Level1) +{ + Media::AVCodecErrorType errorType = Media::AVCODEC_ERROR_EXTEND_START; + int32_t errorCode = DH_SUCCESS; + std::shared_ptr listener= nullptr; + imageDecoder_->imageProcessorListener_ = listener; + imageDecoder_->OnError(errorType, errorCode); +} + +/** + * @tc.name: on_input_buffer_available_test_001 + * @tc.desc: Verify the OnInputBufferAvailable function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_input_buffer_available_test_001, TestSize.Level1) +{ + uint32_t index = 0; + unsigned int len = 1; + imageDecoder_->OnInputBufferAvailable(index); + EXPECT_EQ(len, imageDecoder_->bufferIndexQueue_.size()); +} + +/** + * @tc.name: on_output_buffer_available_test_001 + * @tc.desc: Verify the OnInputBufferAvailable function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_output_buffer_available_test_001, TestSize.Level1) +{ + uint32_t index = 0; + Media::AVCodecBufferFlag flag = Media::AVCODEC_BUFFER_FLAG_CODEC_DATA; + Media::AVCodecBufferInfo info; + info.presentationTimeUs = 1; + + imageDecoder_->OnOutputBufferAvailable(index, info, flag); + EXPECT_EQ(info.presentationTimeUs, imageDecoder_->decoderBufferInfo_.presentationTimeUs); +} + +/** + * @tc.name: on_output_buffer_available_test_002 + * @tc.desc: Verify the OnInputBufferAvailable function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_output_buffer_available_test_002, TestSize.Level1) +{ + uint32_t index = 0; + Media::AVCodecBufferFlag flag = Media::AVCODEC_BUFFER_FLAG_CODEC_DATA; + Media::AVCodecBufferInfo info; + info.presentationTimeUs = 1; + imageDecoder_->decoderBufferInfo_.presentationTimeUs = 0; + + imageDecoder_->videoDecoder_ = nullptr; + imageDecoder_->OnOutputBufferAvailable(index, info, flag); + EXPECT_NE(info.presentationTimeUs, imageDecoder_->decoderBufferInfo_.presentationTimeUs); +} + +/** + * @tc.name: on_output_format_changed_test_001 + * @tc.desc: Verify the OnOutputFormatChanged function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, on_output_format_changed_test_001, TestSize.Level1) +{ + Media::Format format; + imageDecoder_->OnOutputFormatChanged(format); + + EXPECT_EQ(false, imageDecoder_->isDecoderReady_); +} + +/** + * @tc.name: start_input_thread_test_001 + * @tc.desc: Verify the StartInputThread StopInputThread function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, start_input_thread_test_001, TestSize.Level1) +{ + imageDecoder_->videoDecoder_ = nullptr; + + imageDecoder_->StartInputThread(); + EXPECT_EQ(true, imageDecoder_->isDecoderReady_); + + imageDecoder_->StopInputThread(); + EXPECT_EQ(false, imageDecoder_->isDecoderReady_); +} + +/** + * @tc.name: process_data_test_001 + * @tc.desc: Verify the StartInputThread StopInputThread function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkDecoderTest, process_data_test_001, TestSize.Level1) +{ + std::shared_ptr data = std::make_shared(DATA_LEN); + imageDecoder_->videoDataQueue_.push(data); + + uint32_t index = 0; + imageDecoder_->bufferIndexQueue_.push(index); + + imageDecoder_->StartInputThread(); + EXPECT_EQ(true, imageDecoder_->isDecoderReady_); + + imageDecoder_->StopInputThread(); + EXPECT_EQ(false, imageDecoder_->isDecoderReady_); +} +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_processor_test.cpp b/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_processor_test.cpp new file mode 100644 index 00000000..b8a246ea --- /dev/null +++ b/services/screentransport/test/unittest/screensinkprocessor/src/image_sink_processor_test.cpp @@ -0,0 +1,193 @@ +/* + * 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 "image_sink_processor_test.h" + +#include +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ImageSinkProcessorTest::SetUpTestCase(void) {} + +void ImageSinkProcessorTest::TearDownTestCase(void) {} + +void ImageSinkProcessorTest::SetUp(void) +{ + param_.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + param_.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + param_.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + param_.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + param_.fps_ = FPS; + param_.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + param_.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + + processor_ = std::make_shared(); + imageListener_ = std::make_shared(); + processor_->imageDecoder_ = std::make_shared(imageListener_); + processor_->imageDecoder_->videoDecoder_ = Media::VideoDecoderFactory::CreateByName("OMX_hisi_video_decoder_avc"); +} + +void ImageSinkProcessorTest::TearDown(void) {} + +/** + * @tc.name: configure_image_processor_test_001 + * @tc.desc: Verify the ConfigureImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, configure_image_processor_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, processor_->ConfigureImageProcessor(param_, param_, imageListener_)); +} + +/** + * @tc.name: configure_image_processor_test_002 + * @tc.desc: Verify the ConfigureImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, configure_image_processor_test_002, TestSize.Level1) +{ + param_.codecType_ = VIDEO_CODEC_TYPE_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, + processor_->ConfigureImageProcessor(param_, param_, imageListener_)); +} + +/** + * @tc.name: release_image_processor_test_001 + * @tc.desc: Verify the ReleaseImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, release_image_processor_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, processor_->ReleaseImageProcessor()); +} + +/** + * @tc.name: release_image_processor_test_002 + * @tc.desc: Verify the ReleaseImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, release_image_processor_test_002, TestSize.Level1) +{ + processor_->imageDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, processor_->ReleaseImageProcessor()); +} + +/** + * @tc.name: start_image_processor_test_001 + * @tc.desc: Verify the StartImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, start_image_processor_test_001, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_CODEC_PREPARE_FAILED, processor_->StartImageProcessor()); +} + +/** + * @tc.name: start_image_processor_test_002 + * @tc.desc: Verify the StartImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, start_image_processor_test_002, TestSize.Level1) +{ + processor_->imageDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, processor_->StartImageProcessor()); +} + +/** + * @tc.name: stop_image_processor_test_001 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, stop_image_processor_test_001, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_CODEC_FLUSH_FAILED, processor_->StopImageProcessor()); +} + +/** + * @tc.name: stop_image_processor_test_002 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, stop_image_processor_test_002, TestSize.Level1) +{ + processor_->imageDecoder_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, processor_->StopImageProcessor()); +} + +/** + * @tc.name: set_image_surface_test_001 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, set_image_surface_test_001, TestSize.Level1) +{ + sptr surface = Surface::CreateSurfaceAsConsumer("test"); + EXPECT_EQ(ERR_DH_SCREEN_CODEC_SURFACE_ERROR, processor_->SetImageSurface(surface)); +} + +/** + * @tc.name: set_image_surface_test_002 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, set_image_surface_test_002, TestSize.Level1) +{ + processor_->imageDecoder_ = nullptr; + sptr surface = Surface::CreateSurfaceAsConsumer("test"); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, processor_->SetImageSurface(surface)); +} + +/** + * @tc.name: processimage_test_001 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, processimage_test_001, TestSize.Level1) +{ + std::shared_ptr data = std::make_shared(DATA_LEN); + EXPECT_EQ(DH_SUCCESS, processor_->ProcessImage(data)); +} + +/** + * @tc.name: processimage_test_002 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSinkProcessorTest, processimage_test_002, TestSize.Level1) +{ + processor_->imageDecoder_ = nullptr; + std::shared_ptr data = std::make_shared(DATA_LEN); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, processor_->ProcessImage(data)); +} +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinktrans/BUILD.gn b/services/screentransport/test/unittest/screensinktrans/BUILD.gn new file mode 100644 index 00000000..90ecbf79 --- /dev/null +++ b/services/screentransport/test/unittest/screensinktrans/BUILD.gn @@ -0,0 +1,84 @@ +# 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. + +import("//build/test.gni") +import("//build/ohos.gni") +import("//build/ohos_var.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/sink_trans_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + ] + + include_dirs += [ + "./include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/softbusadapter/include", + ] +} + +## UnitTest sink_trans_test +ohos_unittest("SinkTransTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/screentransport/test/unittest/screensinktrans/src/screen_sink_trans_test.cpp" + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensinktrans:distributed_screen_sinktrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"sinktranstest\"", + "LOG_DOMAIN=0xD004100", + ] + + remove_configs = [ "//build/config/compiler:no_rtti" ] + cflags = [ "-frtti" ] + cflags_cc = cflags +} + +group("sink_trans_test") { + testonly = true + deps = [ ":SinkTransTest" ] +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinktrans/include/screen_sink_trans_test.h b/services/screentransport/test/unittest/screensinktrans/include/screen_sink_trans_test.h new file mode 100644 index 00000000..7ad2db3e --- /dev/null +++ b/services/screentransport/test/unittest/screensinktrans/include/screen_sink_trans_test.h @@ -0,0 +1,43 @@ +/* + * 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 SCREEN_SINK_TRANS_TEST_H +#define SCREEN_SINK_TRANS_TEST_H + +#include + +#define private public +#include "screen_sink_trans.h" +#undef private + +#include "iscreen_sink_trans_callback.h" +#include "screentrans_test_utils.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenSinkTransTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr trans_; + VideoParam param_; + std::string peerDevId_; +}; +} +} +#endif \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensinktrans/src/screen_sink_trans_test.cpp b/services/screentransport/test/unittest/screensinktrans/src/screen_sink_trans_test.cpp new file mode 100644 index 00000000..3d88b9bf --- /dev/null +++ b/services/screentransport/test/unittest/screensinktrans/src/screen_sink_trans_test.cpp @@ -0,0 +1,258 @@ +/* + * 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 "screen_sink_trans_test.h" + +#include + +#include "dscreen_errcode.h" +#include "image_sink_processor.h" +#include "screen_data_channel_impl.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ScreenSinkTransTest::SetUpTestCase(void) {} + +void ScreenSinkTransTest::TearDownTestCase(void) {} + +void ScreenSinkTransTest::SetUp(void) +{ + peerDevId_ = "test"; + trans_ = std::make_shared(); + trans_->imageProcessor_ = std::make_shared(); + trans_->screenChannel_ = std::make_shared(peerDevId_); + trans_->decoderSurface_ = Surface::CreateSurfaceAsConsumer("test"); + trans_->transCallback_ = std::make_shared(); + + param_.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + param_.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + param_.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + param_.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + param_.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + param_.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + param_.fps_ = FPS; +} + +void ScreenSinkTransTest::TearDown(void) {} + +/** + * @tc.name: setup_test_001 + * @tc.desc: Verify the SetUp function failed. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, setup_test_001, TestSize.Level1) +{ + param_.screenWidth_ = WIDTH_INVALID; + param_.screenHeight_ = HEIGHT_INVALID; + param_.videoWidth_ = WIDTH_INVALID; + param_.videoHeight_ = HEIGHT_INVALID; + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM, trans_->SetUp(param_, param_, peerDevId_)); +} + +/** + * @tc.name: register_processor_listner_001 + * @tc.desc: Verify the RegisterChannelListner function success. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, register_processor_listner_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, trans_->RegisterProcessorListner(param_, param_, peerDevId_)); +} + +/** + * @tc.name: release_test_001 + * @tc.desc: Verify the Release function success. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, release_test_001, TestSize.Level1) +{ + EXPECT_EQ(DH_SUCCESS, trans_->Release()); +} + +/** + * @tc.name: release_test_002 + * @tc.desc: Verify the Release function fail. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, release_test_002, TestSize.Level1) +{ + trans_->imageProcessor_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, trans_->Release()); +} + +/** + * @tc.name: start_test_002 + * @tc.desc: Verify the Start function fail. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, start_test_002, TestSize.Level1) +{ + trans_->imageProcessor_ = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, trans_->Start()); +} + +/** + * @tc.name: stop_test_002 + * @tc.desc: Verify the Stop function success. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, stop_test_002, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ERROR, trans_->Stop()); +} + +/** + * @tc.name: register_state_callback_test_001 + * @tc.desc: Verify the RegisterStateCallback function success. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, register_state_callback_test_001, TestSize.Level1) +{ + std::shared_ptr callback = + std::make_shared(); + EXPECT_EQ(DH_SUCCESS, trans_->RegisterStateCallback(callback)); +} + +/** + * @tc.name: register_state_callback_test_002 + * @tc.desc: Verify the RegisterStateCallback function fail. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, register_state_callback_test_002, TestSize.Level1) +{ + std::shared_ptr callback = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, trans_->RegisterStateCallback(callback)); +} + +/** + * @tc.name: set_image_surface_test_001 + * @tc.desc: Verify the SetImageSurface function success. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, set_image_surface_test_001, TestSize.Level1) +{ + sptr surface = Surface::CreateSurfaceAsConsumer("test"); + EXPECT_EQ(DH_SUCCESS, trans_->SetImageSurface(surface)); +} + +/** + * @tc.name: set_image_surface_test_002 + * @tc.desc: Verify the SetImageSurface function fail. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, set_image_surface_test_002, TestSize.Level1) +{ + sptr surface = nullptr; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, trans_->SetImageSurface(surface)); +} + +/** + * @tc.name: check_trans_param_test_001 + * @tc.desc: Verify the CheckTransParam function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, check_trans_param_test_001, TestSize.Level1) +{ + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, trans_->CheckTransParam(param_, param_, "")); + + param_.codecType_ = VIDEO_CODEC_TYPE_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM, trans_->CheckTransParam(param_, param_, peerDevId_)); + + param_.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + param_.videoFormat_ = VIDEO_DATA_FORMAT_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM, trans_->CheckTransParam(param_, param_, peerDevId_)); + + param_.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + param_.videoWidth_ = WIDTH_INVALID; + param_.videoHeight_ = HEIGHT_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM, trans_->CheckTransParam(param_, param_, peerDevId_)); + + param_.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + param_.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + param_.screenWidth_ = WIDTH_INVALID; + param_.screenHeight_ = HEIGHT_INVALID; + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM, trans_->CheckTransParam(param_, param_, peerDevId_)); + + param_.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + param_.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + EXPECT_EQ(DH_SUCCESS, trans_->CheckTransParam(param_, param_, peerDevId_)); +} + +/** + * @tc.name: on_session_closed_test_001 + * @tc.desc: Verify the OnSessionClosed function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, on_session_closed_test_001, TestSize.Level1) +{ + trans_->transCallback_ = std::make_shared(); + trans_->OnSessionClosed(); +} + +/** + * @tc.name: on_data_received_test_001 + * @tc.desc: Verify the OnDataReceived function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, on_data_received_test_001, TestSize.Level1) +{ + std::shared_ptr dataBuffer = nullptr; + trans_->OnDataReceived(dataBuffer); +} + +/** + * @tc.name: on_processor_state_notify_test_001 + * @tc.desc: Verify the RegisterChannelListner function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, on_processor_state_notify_test_001, TestSize.Level1) +{ + int32_t state = DH_SUCCESS; + trans_->transCallback_ = std::make_shared(); + trans_->OnProcessorStateNotify(state); +} + +/** + * @tc.name: on_processor_state_notify_test_002 + * @tc.desc: Verify the RegisterChannelListner function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSinkTransTest, on_processor_state_notify_test_002, TestSize.Level1) +{ + int32_t state = DH_SUCCESS; + std::shared_ptr callback = nullptr; + trans_->transCallback_ = callback; + trans_->OnProcessorStateNotify(state); +} +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensourceprocessor/BUILD.gn b/services/screentransport/test/unittest/screensourceprocessor/BUILD.gn new file mode 100644 index 00000000..2f935349 --- /dev/null +++ b/services/screentransport/test/unittest/screensourceprocessor/BUILD.gn @@ -0,0 +1,75 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/source_processor_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/", + ] + + include_dirs += [ + "./include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/test/unittest/screensourcetrans", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/softbusadapter/include", + "${services_path}/screentransport/test/unittest/screensourceprocessor/include", + ] +} + +## UnitTest screen_source_processor_test +ohos_unittest("SourceProcessorTest") { + module_out_path = module_out_path + + sources = [ + "${services_path}/screentransport/test/unittest/screensourceprocessor/src/image_source_processor_test.cpp", + "${services_path}/screentransport/test/unittest/screensourceprocessor/src/image_source_encoder_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] +} + +group("source_processor_test") { + testonly = true + deps = [ ":SourceProcessorTest" ] +} diff --git a/services/screentransport/test/unittest/screensourceprocessor/include/image_source_encoder_test.h b/services/screentransport/test/unittest/screensourceprocessor/include/image_source_encoder_test.h new file mode 100644 index 00000000..f9d3fadd --- /dev/null +++ b/services/screentransport/test/unittest/screensourceprocessor/include/image_source_encoder_test.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. + */ + +#include +#include + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#define private public +#include "image_source_encoder.h" +#undef private + +namespace OHOS { +namespace DistributedHardware { +class ImageSourceEncoderTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr encoder = nullptr; +}; +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensourceprocessor/include/image_source_processor_test.h b/services/screentransport/test/unittest/screensourceprocessor/include/image_source_processor_test.h new file mode 100644 index 00000000..3dfafb36 --- /dev/null +++ b/services/screentransport/test/unittest/screensourceprocessor/include/image_source_processor_test.h @@ -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 + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#define private public +#include "image_source_processor.h" +#undef private + +namespace OHOS { +namespace DistributedHardware { +class ImageSourceProcessorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + ImageSourceProcessor processor; +}; +} +} \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensourceprocessor/src/image_source_encoder_test.cpp b/services/screentransport/test/unittest/screensourceprocessor/src/image_source_encoder_test.cpp new file mode 100644 index 00000000..4805246f --- /dev/null +++ b/services/screentransport/test/unittest/screensourceprocessor/src/image_source_encoder_test.cpp @@ -0,0 +1,204 @@ +/* + * 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 "image_source_encoder_test.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ImageSourceEncoderTest::SetUpTestCase(void) {} + +void ImageSourceEncoderTest::TearDownTestCase(void) {} + +void ImageSourceEncoderTest::SetUp(void) +{ + std::shared_ptr imageListener = nullptr; + encoder = std::make_shared(imageListener); +} + +void ImageSourceEncoderTest::TearDown(void) {} + +/** + * @tc.name: ConfigureEncoder_001 + * @tc.desc: Verify the ConfigureEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, ConfigureEncoder_001, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + configParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + + int32_t actual = encoder->ConfigureEncoder(configParam); + EXPECT_EQ(ERR_DH_SCREEN_CODEC_SURFACE_ERROR, actual); +} + +/** + * @tc.name: ConfigureEncoder_002 + * @tc.desc: Verify the ConfigureEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, ConfigureEncoder_002, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = -1; + + int32_t actual = encoder->ConfigureEncoder(configParam); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_CREATE_CODEC_FAILED, actual); +} + +/** + * @tc.name: ReleaseEncoder_001 + * @tc.desc: Verify the ReleaseEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, ReleaseEncoder_001, TestSize.Level1) +{ + int32_t actual = encoder->ReleaseEncoder(); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: ReleaseEncoder_002 + * @tc.desc: Verify the ReleaseEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, ReleaseEncoder_002, TestSize.Level1) +{ + encoder->videoEncoder_ = Media::VideoEncoderFactory::CreateByMime("video/avc"); + + int32_t actual = encoder->ReleaseEncoder(); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: StartEncoder_001 + * @tc.desc: Verify the StartEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, StartEncoder_001, TestSize.Level1) +{ + int32_t actual = encoder->StartEncoder(); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StartEncoder_002 + * @tc.desc: Verify the StartEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, StartEncoder_002, TestSize.Level1) +{ + encoder->videoEncoder_ = Media::VideoEncoderFactory::CreateByMime("video/avc"); + + int32_t actual = encoder->StartEncoder(); + EXPECT_EQ(ERR_DH_SCREEN_CODEC_PREPARE_FAILED, actual); +} + +/** + * @tc.name: StopEncoder_001 + * @tc.desc: Verify the StopEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, StopEncoder_001, TestSize.Level1) +{ + int32_t actual = encoder->StopEncoder(); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StopEncoder_002 + * @tc.desc: Verify the StartEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, StopEncoder_002, TestSize.Level1) +{ + encoder->videoEncoder_ = Media::VideoEncoderFactory::CreateByMime("video/avc"); + + int32_t actual = encoder->StopEncoder(); + EXPECT_EQ(ERR_DH_SCREEN_CODEC_STOP_FAILED, actual); +} + +/** + * @tc.name: InitVideoEncoder_001 + * @tc.desc: Verify the InitVideoEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, InitVideoEncoder_001, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + + int32_t actual = encoder->InitVideoEncoder(configParam); + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: InitVideoEncoder_002 + * @tc.desc: Verify the InitVideoEncoder function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, InitVideoEncoder_002, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = -1; + + int32_t actual = encoder->InitVideoEncoder(configParam); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_CREATE_CODEC_FAILED, actual); +} + +/** + * @tc.name: SetEncoderFormat_001 + * @tc.desc: Verify the SetEncoderFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, SetEncoderFormat_001, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + configParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + + int32_t actual = encoder->SetEncoderFormat(configParam); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: SetEncoderFormat_002 + * @tc.desc: Verify the SetEncoderFormat function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceEncoderTest, SetEncoderFormat_002, TestSize.Level1) +{ + VideoParam configParam; + configParam.codecType_ = -1; + + int32_t actual = encoder->SetEncoderFormat(configParam); + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} +} // DistributedHardware +} // OHOS \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensourceprocessor/src/image_source_processor_test.cpp b/services/screentransport/test/unittest/screensourceprocessor/src/image_source_processor_test.cpp new file mode 100644 index 00000000..f5cc926b --- /dev/null +++ b/services/screentransport/test/unittest/screensourceprocessor/src/image_source_processor_test.cpp @@ -0,0 +1,164 @@ +/* + * 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 "image_source_processor_test.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ImageSourceProcessorTest::SetUpTestCase(void) {} + +void ImageSourceProcessorTest::TearDownTestCase(void) {} + +void ImageSourceProcessorTest::SetUp(void) {} + +void ImageSourceProcessorTest::TearDown(void) {} + +/** + * @tc.name: ConfigureImageProcessor_001 + * @tc.desc: Verify the ConfigureImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, ConfigureImageProcessor_001, TestSize.Level1) +{ + VideoParam localParam; + VideoParam remoteParam; + std::shared_ptr listener = nullptr; + + int32_t actual = processor.ConfigureImageProcessor(localParam, remoteParam, listener); + + EXPECT_EQ(ERR_DH_SCREEN_CODEC_SURFACE_ERROR, actual); +} + +/** + * @tc.name: ConfigureImageProcessor_002 + * @tc.desc: Verify the ConfigureImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, ConfigureImageProcessor_002, TestSize.Level1) +{ + VideoParam localParam; + localParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + VideoParam remoteParam; + std::shared_ptr listener = nullptr; + + int32_t actual = processor.ConfigureImageProcessor(localParam, remoteParam, listener); + + EXPECT_EQ(ERR_DH_SCREEN_CODEC_SURFACE_ERROR, actual); +} + +/** + * @tc.name: ReleaseImageProcessor_001 + * @tc.desc: Verify the ReleaseImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, ReleaseImageProcessor_001, TestSize.Level1) +{ + int32_t actual = processor.ReleaseImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: ReleaseImageProcessor_002 + * @tc.desc: Verify the ReleaseImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, ReleaseImageProcessor_002, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + processor.imageEncoder_ = std::make_shared(listener); + int32_t actual = processor.ReleaseImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StartImageProcessor_001 + * @tc.desc: Verify the StartImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, StartImageProcessor_001, TestSize.Level1) +{ + int32_t actual = processor.StartImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StartImageProcessor_002 + * @tc.desc: Verify the StartImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, StartImageProcessor_002, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + processor.imageEncoder_ = std::make_shared(listener); + int32_t actual = processor.StartImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StopImageProcessor_001 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, StopImageProcessor_001, TestSize.Level1) +{ + int32_t actual = processor.StopImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: StopImageProcessor_002 + * @tc.desc: Verify the StopImageProcessor function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, StopImageProcessor_002, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + processor.imageEncoder_ = std::make_shared(listener); + int32_t actual = processor.StopImageProcessor(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: GetImageSurface_001 + * @tc.desc: Verify the GetImageSurface function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ImageSourceProcessorTest, GetImageSurface_001, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + processor.imageEncoder_ = std::make_shared(listener); + sptr actual = processor.GetImageSurface(); + + EXPECT_EQ(nullptr, actual); +} +} // DistributedHardware +} // OHOS \ No newline at end of file diff --git a/services/screentransport/test/unittest/screensourcetrans/BUILD.gn b/services/screentransport/test/unittest/screensourcetrans/BUILD.gn new file mode 100644 index 00000000..09c1d986 --- /dev/null +++ b/services/screentransport/test/unittest/screensourcetrans/BUILD.gn @@ -0,0 +1,75 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/source_trans_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/log/include", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/", + "${fwk_utils_path}/include/log", + ] + + include_dirs += [ + "./include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/test/unittest/screensourcetrans/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/softbusadapter/include", + ] +} + +## UnitTest screen_source_trans_test +ohos_unittest("SourceTransTest") { + module_out_path = module_out_path + + sources = [ "${services_path}/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] +} + +group("source_trans_test") { + testonly = true + deps = [ ":SourceTransTest" ] +} diff --git a/services/screentransport/test/unittest/screensourcetrans/include/screen_source_trans_test.h b/services/screentransport/test/unittest/screensourcetrans/include/screen_source_trans_test.h new file mode 100644 index 00000000..333cb9ed --- /dev/null +++ b/services/screentransport/test/unittest/screensourcetrans/include/screen_source_trans_test.h @@ -0,0 +1,39 @@ +/* + * 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 +#include + +#define private public +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "image_source_processor.h" +#include "screen_data_channel_impl.h" +#include "screen_source_trans.h" +#undef private + +namespace OHOS { +namespace DistributedHardware { +class ScreenSourceTransTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr trans = nullptr; +}; +} +} diff --git a/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp b/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp new file mode 100644 index 00000000..f0a5f3ae --- /dev/null +++ b/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp @@ -0,0 +1,226 @@ +/* + * 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 "screen_source_trans_test.h" +#include "screentrans_test_utils.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void ScreenSourceTransTest::SetUpTestCase(void) {} + +void ScreenSourceTransTest::TearDownTestCase(void) {} + +void ScreenSourceTransTest::SetUp(void) +{ + trans = std::make_shared(); +} + +void ScreenSourceTransTest::TearDown(void) {} + +/** + * @tc.name: SetUp_001 + * @tc.desc: Verify the SetUp function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, SetUp_001, TestSize.Level1) +{ + VideoParam localParam; + VideoParam remoteParam; + std::string peerDevId; + + int32_t actual = trans->SetUp(localParam, remoteParam, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: SetUp_002 + * @tc.desc: Verify the SetUp function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, SetUp_002, TestSize.Level1) +{ + VideoParam localParam; + localParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + localParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + localParam.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + localParam.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + localParam.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + localParam.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + VideoParam remoteParam; + remoteParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + remoteParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + remoteParam.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + remoteParam.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + remoteParam.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + remoteParam.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + std::string peerDevId = "hello"; + + int32_t actual = trans->SetUp(localParam, remoteParam, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: Release_001 + * @tc.desc: Verify the Release function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, Release_001, TestSize.Level1) +{ + int32_t actual = trans->Release(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: Release_002 + * @tc.desc: Verify the Release function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, Release_002, TestSize.Level1) +{ + trans->imageProcessor_ = std::make_shared(); + std::string peerDevId = "hello"; + trans->screenChannel_ = std::make_shared(peerDevId); + int32_t actual = trans->Release(); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: Start_001 + * @tc.desc: Verify the Start function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, Start_001, TestSize.Level1) +{ + int32_t actual = trans->Start(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: Start_002 + * @tc.desc: Verify the Start function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, Start_002, TestSize.Level1) +{ + trans->imageProcessor_ = std::make_shared(); + std::string peerDevId = "hello"; + trans->screenChannel_ = std::make_shared(peerDevId); + int32_t actual = trans->Start(); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ERROR, actual); +} + +/** + * @tc.name: RegisterStateCallback_001 + * @tc.desc: Verify the RegisterStateCallback function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, RegisterStateCallback_001, TestSize.Level1) +{ + std::shared_ptr callback = nullptr; + int32_t actual = trans->RegisterStateCallback(callback); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: RegisterStateCallback_002 + * @tc.desc: Verify the RegisterStateCallback function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, RegisterStateCallback_002, TestSize.Level1) +{ + std::shared_ptr callback = + std::make_shared(); + int32_t actual = trans->RegisterStateCallback(callback); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: CheckTransParam_001 + * @tc.desc: Verify the CheckTransParam function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, CheckTransParam_001, TestSize.Level1) +{ + VideoParam localParam; + VideoParam remoteParam; + std::string peerDevId; + int32_t actual = trans->CheckTransParam(localParam, remoteParam, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_NULL_VALUE, actual); +} + +/** + * @tc.name: CheckTransParam_002 + * @tc.desc: Verify the CheckTransParam function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, CheckTransParam_002, TestSize.Level1) +{ + VideoParam localParam; + localParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + localParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + localParam.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + localParam.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + localParam.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + localParam.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + VideoParam remoteParam; + remoteParam.codecType_ = VIDEO_CODEC_TYPE_VIDEO_H264; + remoteParam.videoFormat_ = VIDEO_DATA_FORMAT_YUVI420; + remoteParam.videoWidth_ = DSCREEN_MAX_VIDEO_DATA_WIDTH; + remoteParam.videoHeight_ = DSCREEN_MAX_VIDEO_DATA_HEIGHT; + remoteParam.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; + remoteParam.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; + std::string peerDevId = "hello"; + int32_t actual = trans->CheckTransParam(localParam, remoteParam, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: OnSessionOpened_001 + * @tc.desc: Verify the OnSessionOpened function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(ScreenSourceTransTest, OnSessionOpened_001, TestSize.Level1) +{ + trans->imageProcessor_ = std::make_shared(); + + trans->OnSessionOpened(); + + EXPECT_EQ(false, trans->isChannelReady_); +} +} +} diff --git a/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h b/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h new file mode 100644 index 00000000..407b5413 --- /dev/null +++ b/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h @@ -0,0 +1,81 @@ +/* + * 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 SCREENTRANS_TEST_UTILS_H +#define SCREENTRANS_TEST_UTILS_H + +#include "dscreen_errcode.h" +#include "dscreen_log.h" +#include "iimage_sink_processor_listener.h" +#include "iscreen_sink_trans_callback.h" +#include "iscreen_source_trans_callback.h" +#include "iscreen_channel_listener.h" + +namespace OHOS { +namespace DistributedHardware { +constexpr int32_t VIDEO_CODEC_TYPE_INVALID = -1; +constexpr int32_t VIDEO_DATA_FORMAT_INVALID = -1; +constexpr int32_t WIDTH_INVALID = 9999; +constexpr int32_t HEIGHT_INVALID = 9999; +constexpr int32_t FPS = 30; +constexpr size_t DATA_LEN = 128; + +class MockIScreenSinkTransCallback : public IScreenSinkTransCallback { +public: + explicit MockIScreenSinkTransCallback() + { + } + ~MockIScreenSinkTransCallback() override = default; + + virtual void OnError(int32_t err, const std::string &content) override + { + (void) err; + (void) content; + } +}; + +class MockIImageSinkProcessorListener : public IImageSinkProcessorListener { +public: + explicit MockIImageSinkProcessorListener() + { + } + ~MockIImageSinkProcessorListener() override = default; + + virtual void OnProcessorStateNotify(int32_t state) override + { + (void) state; + } +}; + +class MockIScreenSourceTransCallback : public IScreenSourceTransCallback { +public: + ~MockIScreenSourceTransCallback() override {}; + + virtual void OnError(int32_t err, const std::string &content) override + { + (void) err; + (void) content; + } +}; + +class MockIScreenChannelListener : public IScreenChannelListener { +public: + void OnSessionOpened() override {} + void OnSessionClosed() override {} + void OnDataReceived(const std::shared_ptr &data) override {} +}; +} +} +#endif \ No newline at end of file diff --git a/services/softbusadapter/include/isoftbus_listener.h b/services/softbusadapter/include/isoftbus_listener.h new file mode 100644 index 00000000..87450909 --- /dev/null +++ b/services/softbusadapter/include/isoftbus_listener.h @@ -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. + */ + +#ifndef OHOS_ISOFTBUS_LISTENER +#define OHOS_ISOFTBUS_LISTENER + +#include "data_buffer.h" +#include "session.h" + +namespace OHOS { +namespace DistributedHardware { +class ISoftbusListener { +public: + virtual ~ISoftbusListener() = default; + + virtual void OnSessionOpened(int32_t sessionId, int32_t result) = 0; + virtual void OnSessionClosed(int32_t sessionId) = 0; + virtual void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) = 0; + virtual void OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) = 0; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/softbusadapter/include/softbus_adapter.h b/services/softbusadapter/include/softbus_adapter.h new file mode 100644 index 00000000..3d556675 --- /dev/null +++ b/services/softbusadapter/include/softbus_adapter.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SOFTBUS_ADAPTER +#define OHOS_SOFTBUS_ADAPTER + +#include +#include +#include + +#include "session.h" +#include "single_instance.h" + +#include "dscreen_constants.h" +#include "dscreen_log.h" +#include "isoftbus_listener.h" + +namespace OHOS { +namespace DistributedHardware { +typedef struct { + std::string sessionName; + std::string peerDevId; +} SessionInfo; + +class SoftbusAdapter { + DECLARE_SINGLE_INSTANCE_BASE(SoftbusAdapter); +public: + int32_t CreateSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName, + const std::string &peerDevId); + int32_t RemoveSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName, + const std::string &peerDevId); + int32_t OpenSoftbusSession(const std::string &mySessionName, const std::string &peerSessionName, + const std::string &peerDevId); + int32_t CloseSoftbusSession(int32_t sessionId); + int32_t SendSoftbusBytes(int32_t sessionId, const void *data, int32_t dataLen); + int32_t SendSoftbusStream(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param); + int32_t RegisterSoftbusListener(const std::shared_ptr &listener, const std::string &sessionName, + const std::string &peerDevId); + int32_t UnRegisterSoftbusListener(const std::string &sessionName, const std::string &peerDevId); + + int32_t OnSoftbusSessionOpened(int32_t sessionId, int32_t result); + void OnSoftbusSessionClosed(int32_t sessionId); + void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen); + void OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *StreamFrameInfo); + void OnMessageReceived(int sessionId, const void *data, unsigned int dataLen); + void OnQosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList); + +private: + SoftbusAdapter(); + ~SoftbusAdapter(); + std::shared_ptr &GetSoftbusListenerByName(int32_t sessionId); + std::shared_ptr &GetSoftbusListenerById(int32_t sessionId); + +private: + static const constexpr char *LOG_TAG = "SoftbusAdapter"; + std::mutex listenerMtx_; + std::mutex sessInfoMtx_; + std::mutex sessSetMtx_; + + ISessionListener sessListener_; + /* while can not find the listener in mapListeners_, return nullListener_ point to null ptr. */ + std::shared_ptr nullListener_; + std::map mapSessionInfos_; + std::map> mapSessionSet_; + std::map> mapListeners_; + std::map> mapSessListeners_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/softbusadapter/src/softbus_adapter.cpp b/services/softbusadapter/src/softbus_adapter.cpp new file mode 100644 index 00000000..30ce06b7 --- /dev/null +++ b/services/softbusadapter/src/softbus_adapter.cpp @@ -0,0 +1,343 @@ +/* + * 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 "softbus_adapter.h" + +#include + +#include "softbus_bus_center.h" +#include "softbus_common.h" + +#include "dscreen_errcode.h" +#include "dscreen_util.h" + +namespace OHOS { +namespace DistributedHardware { +IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter); +static int32_t ScreenOnSoftbusSessionOpened(int32_t sessionId, int32_t result) +{ + return SoftbusAdapter::GetInstance().OnSoftbusSessionOpened(sessionId, result); +} + +static void ScreenOnSoftbusSessionClosed(int32_t sessionId) +{ + SoftbusAdapter::GetInstance().OnSoftbusSessionClosed(sessionId); +} + +static void ScreenOnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + SoftbusAdapter::GetInstance().OnBytesReceived(sessionId, data, dataLen); +} + +static void ScreenOnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *frameInfo) +{ + SoftbusAdapter::GetInstance().OnStreamReceived(sessionId, data, ext, frameInfo); +} + +static void ScreenOnMessageReceived(int sessionId, const void *data, unsigned int dataLen) +{ + SoftbusAdapter::GetInstance().OnMessageReceived(sessionId, data, dataLen); +} + +static void ScreenOnQosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList) +{ + SoftbusAdapter::GetInstance().OnQosEvent(sessionId, eventId, tvCount, tvList); +} + +SoftbusAdapter::SoftbusAdapter() +{ + DHLOGI("SoftbusAdapter"); + sessListener_.OnSessionOpened = ScreenOnSoftbusSessionOpened; + sessListener_.OnSessionClosed = ScreenOnSoftbusSessionClosed; + sessListener_.OnBytesReceived = ScreenOnBytesReceived; + sessListener_.OnStreamReceived = ScreenOnStreamReceived; + sessListener_.OnMessageReceived = ScreenOnMessageReceived; + sessListener_.OnQosEvent = ScreenOnQosEvent; +} + +SoftbusAdapter::~SoftbusAdapter() +{ + DHLOGI("~SoftbusAdapter"); +} + +int32_t SoftbusAdapter::RegisterSoftbusListener(const std::shared_ptr &listener, + const std::string &sessionName, const std::string &peerDevId) +{ + DHLOGI("%s: RegisterListener sess:%s id:%s.", LOG_TAG, sessionName.c_str(), GetAnonyString(peerDevId).c_str()); + std::string strListenerKey = sessionName + "_" + peerDevId; + + std::lock_guard lisLock(listenerMtx_); + if (mapListeners_.find(strListenerKey) != mapListeners_.end()) { + DHLOGE("%s: Session listener already register.", LOG_TAG); + return ERR_DH_SCREEN_ADAPTER_REGISTER_SOFTBUS_LISTENER_FAIL; + } + mapListeners_.insert(std::make_pair(strListenerKey, listener)); + + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::UnRegisterSoftbusListener(const std::string &sessionName, const std::string &peerDevId) +{ + DHLOGI("%s: UnRegisterListener sess:%s id:%s.", LOG_TAG, sessionName.c_str(), GetAnonyString(peerDevId).c_str()); + std::string strListenerKey = sessionName + "_" + peerDevId; + + std::lock_guard lisLock(listenerMtx_); + mapListeners_.erase(strListenerKey); + + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::CreateSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName, + const std::string &peerDevId) +{ + DHLOGI("%s: CreateSessionServer sess:%s id:%s.", LOG_TAG, sessionName.c_str(), GetAnonyString(peerDevId).c_str()); + std::lock_guard setLock(sessSetMtx_); + if (mapSessionSet_.find(sessionName) == mapSessionSet_.end()) { + int32_t ret = CreateSessionServer(pkgname.c_str(), sessionName.c_str(), &sessListener_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: CreateSessionServer failed.", LOG_TAG); + return ret; + } + } else { + DHLOGD("%s: Session already create.", sessionName.c_str()); + } + + mapSessionSet_[sessionName].insert(peerDevId); + DHLOGI("%s: CreateSessionServer success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::RemoveSoftbusSessionServer(const std::string &pkgname, const std::string &sessionName, + const std::string &peerDevId) +{ + DHLOGI("%s: RemoveSessionServer sess:%s id:%s", LOG_TAG, sessionName.c_str(), GetAnonyString(peerDevId).c_str()); + std::lock_guard setLock(sessSetMtx_); + if (mapSessionSet_.find(sessionName) == mapSessionSet_.end()) { + DHLOGE("%s: Session name can not find.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION; + } else if (mapSessionSet_[sessionName].find(peerDevId) == mapSessionSet_[sessionName].end()) { + DHLOGE("%s: PeerDevId can not find.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION; + } + + mapSessionSet_[sessionName].erase(peerDevId); + if (mapSessionSet_[sessionName].empty()) { + mapSessionSet_.erase(sessionName); + } + DHLOGI("%s: RemoveSessionServer success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::OpenSoftbusSession(const std::string &mySessionName, const std::string &peerSessionName, + const std::string &peerDevId) +{ + DHLOGI("%s: OpenSoftbusSession mysess:%s peersess:%s id:%s.", LOG_TAG, mySessionName.c_str(), + peerSessionName.c_str(), GetAnonyString(peerDevId).c_str()); + int dataType = TYPE_BYTES; + int streamType = -1; + if (mySessionName == DATA_SESSION_NAME) { + dataType = TYPE_STREAM; + streamType = RAW_STREAM; + } + + SessionAttribute attr = { 0 }; + attr.dataType = dataType; + attr.linkTypeNum = LINK_TYPE_MAX; + LinkType linkTypeList[LINK_TYPE_MAX] = { + LINK_TYPE_WIFI_P2P, + LINK_TYPE_WIFI_WLAN_5G, + LINK_TYPE_WIFI_WLAN_2G, + LINK_TYPE_BR, + }; + int32_t ret = memcpy_s(attr.linkType, sizeof(attr.linkType), linkTypeList, sizeof(linkTypeList)); + if (ret != EOK) { + DHLOGE("%s: Data copy failed.", LOG_TAG); + return ERR_DH_SCREEN_ADAPTER_PARA_ERROR; + } + attr.attr.streamAttr.streamType = streamType; + int32_t sessionId = OpenSession(mySessionName.c_str(), peerSessionName.c_str(), peerDevId.c_str(), "0", &attr); + if (sessionId < 0) { + DHLOGE("%s: OpenSession failed sessionId:%d.", LOG_TAG, sessionId); + return ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL; + } + + DHLOGI("%s: OpenSoftbusSession success sessionId:%d.", LOG_TAG, sessionId); + return sessionId; +} + +int32_t SoftbusAdapter::CloseSoftbusSession(const int32_t sessionId) +{ + DHLOGI("%s: CloseSoftbusSession, sessid:%d.", LOG_TAG, sessionId); + CloseSession(sessionId); + + std::lock_guard lisLock(listenerMtx_); + mapSessListeners_.erase(sessionId); + + DHLOGI("%s: CloseSoftbusSession success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::SendSoftbusBytes(int32_t sessionId, const void *data, int32_t dataLen) +{ + DHLOGD("%s: SendSoftbusBytes, sessid:%d.", LOG_TAG, sessionId); + int32_t ret = SendBytes(sessionId, data, dataLen); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SendBytes failed ret:%d.", LOG_TAG, ret); + return ERR_DH_SCREEN_TRANS_ERROR; + } + + return DH_SUCCESS; +} + +int32_t SoftbusAdapter::SendSoftbusStream(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *param) +{ + DHLOGD("%s: SendSoftbusStream, sessid:%d.", LOG_TAG, sessionId); + int32_t ret = SendStream(sessionId, data, ext, param); + if (ret != DH_SUCCESS) { + DHLOGE("%s: SendStream failed ret:%d.", LOG_TAG, ret); + return ERR_DH_SCREEN_TRANS_ERROR; + } + + return DH_SUCCESS; +} + +std::shared_ptr &SoftbusAdapter::GetSoftbusListenerByName(int32_t sessionId) +{ + char sessionName[DSCREEN_MAX_SESSION_NAME_LEN] = ""; + char peerDevId[DSCREEN_MAX_DEVICE_ID_LEN] = ""; + int32_t ret = GetPeerSessionName(sessionId, sessionName, sizeof(sessionName)); + if (ret != DH_SUCCESS) { + DHLOGE("%s: GetPeerSessionName failed ret:%d.", LOG_TAG, ret); + return nullListener_; + } + ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); + if (ret != DH_SUCCESS) { + DHLOGE("%s: GetPeerDeviceId failed ret:%d.", LOG_TAG, ret); + return nullListener_; + } + + std::string sessionNameStr(sessionName); + std::string peerDevIdStr(peerDevId); + DHLOGD("%s: GetSoftbusListenerByName sessionName:%s, peerDevId:%s.", LOG_TAG, sessionNameStr.c_str(), + GetAnonyString(peerDevIdStr).c_str()); + std::string strListenerKey = sessionNameStr + "_" + peerDevIdStr; + + std::lock_guard lisLock(listenerMtx_); + if (mapListeners_.find(strListenerKey) == mapListeners_.end()) { + DHLOGE("%s: Find listener failed.", LOG_TAG); + return nullListener_; + } + return mapListeners_[strListenerKey]; +} + +std::shared_ptr &SoftbusAdapter::GetSoftbusListenerById(int32_t sessionId) +{ + std::lock_guard lisLock(listenerMtx_); + if (mapSessListeners_.find(sessionId) == mapSessListeners_.end()) { + DHLOGE("%s: Find listener failed.", LOG_TAG); + return nullListener_; + } + + return mapSessListeners_[sessionId]; +} + +int32_t SoftbusAdapter::OnSoftbusSessionOpened(int32_t sessionId, int32_t result) +{ + DHLOGI("%s: OnSessionOpened session:%d, result:%d.", LOG_TAG, sessionId, result); + if (result != DH_SUCCESS) { + DHLOGE("%s: OnSessionOpened failed.", LOG_TAG); + return ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL; + } + + std::shared_ptr &listener = GetSoftbusListenerByName(sessionId); + if (!listener) { + DHLOGE("Get softbus listener failed."); + return ERR_DH_SCREEN_TRANS_ERROR; + } + listener->OnSessionOpened(sessionId, result); + + std::lock_guard lisLock(listenerMtx_); + mapSessListeners_.insert(std::make_pair(sessionId, listener)); + + return DH_SUCCESS; +} + +void SoftbusAdapter::OnSoftbusSessionClosed(int32_t sessionId) +{ + DHLOGI("%s: OnSessionClosed sessionId:%d.", LOG_TAG, sessionId); + std::shared_ptr &listener = GetSoftbusListenerById(sessionId); + if (!listener) { + DHLOGE("Get softbus listener failed."); + return; + } + listener->OnSessionClosed(sessionId); + + std::lock_guard lisLock(listenerMtx_); + mapSessListeners_.erase(sessionId); +} + +void SoftbusAdapter::OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) +{ + DHLOGD("%s: OnBytesReceived, sessionId:%d.", LOG_TAG, sessionId); + if (data == nullptr) { + DHLOGE("BytesData is null."); + return; + } + if (dataLen == 0 || dataLen > DSCREEN_MAX_RECV_DATA_LEN) { + DHLOGE("BytesData length is too large, dataLen:%u.", dataLen); + return; + } + + std::shared_ptr &listener = GetSoftbusListenerByName(sessionId); + if (!listener) { + DHLOGE("Get softbus listener failed."); + return; + } + listener->OnBytesReceived(sessionId, data, dataLen); +} + +void SoftbusAdapter::OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, + const StreamFrameInfo *frameInfo) +{ + DHLOGD("%s OnStreamReceived, sessionId:%d.", LOG_TAG, sessionId); + if (data == nullptr) { + DHLOGE("StreamData is null."); + return; + } + if (data->bufLen <= 0 || data->bufLen > (int32_t)DSCREEN_MAX_RECV_DATA_LEN) { + DHLOGE("StreamData length is too large, dataLen:%d.", data->bufLen); + return; + } + + std::shared_ptr &listener = GetSoftbusListenerByName(sessionId); + if (!listener) { + DHLOGE("Get softbus listener failed."); + } + listener->OnStreamReceived(sessionId, data, ext, frameInfo); +} + +void SoftbusAdapter::OnMessageReceived(int sessionId, const void *data, unsigned int dataLen) +{ + DHLOGD("%s OnMessageReceived, sessionId:%d.", LOG_TAG, sessionId); +} + +void SoftbusAdapter::OnQosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList) +{ + DHLOGD("%s OnQosEvent, sessionId:%d.", LOG_TAG, sessionId); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/softbusadapter/test/unittest/BUILD.gn b/services/softbusadapter/test/unittest/BUILD.gn new file mode 100644 index 00000000..53959db3 --- /dev/null +++ b/services/softbusadapter/test/unittest/BUILD.gn @@ -0,0 +1,70 @@ +# 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. + +import("//build/test.gni") +import("//foundation/distributedhardware/distributedscreen/distributedscreen.gni") + +module_out_path = "distributed_screen/soft_bus_adapter_test" + +config("module_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "//third_party/json/include", + "//foundation/graphic/standard/interfaces/innerkits/surface", + "${fwk_common_path}/utils/include", + "${fwk_utils_path}/include/", + ] + + include_dirs += [ + "./include", + "${common_path}/include", + "${services_path}/common/databuffer/include", + "${services_path}/common/screen_channel/include", + "${services_path}/common/utils/include", + "${services_path}/screentransport/test/unittest/screensourcetrans/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/softbusadapter/include", + ] +} + +## UnitTest screen_soft_bus_adapter_test +ohos_unittest("SoftBusAdapterTest") { + module_out_path = module_out_path + + sources = [ "${services_path}/softbusadapter/test/unittest/src/softbus_adapter_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", + "${fwk_utils_path}:distributedhardwareutils", + "//foundation/graphic/standard/frameworks/surface:surface", + "//utils/native/base:utils", + ] + + external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "multimedia_media_standard:media_client", + ] +} + +group("soft_bus_adapter_test") { + testonly = true + deps = [ ":SoftBusAdapterTest" ] +} diff --git a/services/softbusadapter/test/unittest/include/softbus_adapter_test.h b/services/softbusadapter/test/unittest/include/softbus_adapter_test.h new file mode 100644 index 00000000..3f494d4f --- /dev/null +++ b/services/softbusadapter/test/unittest/include/softbus_adapter_test.h @@ -0,0 +1,40 @@ +/* + * 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 +#include + +#include "softbus_bus_center.h" +#include "softbus_common.h" + +#include "dscreen_errcode.h" +#include "dscreen_util.h" +#define private public +#include "softbus_adapter.h" +#undef private + +namespace OHOS { +namespace DistributedHardware { +class SoftbusAdapterTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + SoftbusAdapter softbusAdapter; +}; +} +} \ No newline at end of file diff --git a/services/softbusadapter/test/unittest/src/softbus_adapter_test.cpp b/services/softbusadapter/test/unittest/src/softbus_adapter_test.cpp new file mode 100644 index 00000000..d696f705 --- /dev/null +++ b/services/softbusadapter/test/unittest/src/softbus_adapter_test.cpp @@ -0,0 +1,303 @@ +/* + * 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 "softbus_adapter_test.h" + +using namespace testing::ext; + +namespace OHOS { +namespace DistributedHardware { +void SoftbusAdapterTest::SetUpTestCase(void) {} + +void SoftbusAdapterTest::TearDownTestCase(void) {} + +void SoftbusAdapterTest::SetUp(void) {} + +void SoftbusAdapterTest::TearDown(void) {} + +/** + * @tc.name: RegisterSoftbusListener_001 + * @tc.desc: Verify the RegisterSoftbusListener function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, RegisterSoftbusListener_001, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + std::string sessionName; + std::string peerDevId; + + int32_t actual = softbusAdapter.RegisterSoftbusListener(listener, sessionName, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: RegisterSoftbusListener_002 + * @tc.desc: Verify the RegisterSoftbusListener function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, RegisterSoftbusListener_002, TestSize.Level1) +{ + std::shared_ptr listener = nullptr; + std::string sessionName = "hello"; + std::string peerDevId = "world"; + + softbusAdapter.mapListeners_["hello_world"] = listener; + int32_t actual = softbusAdapter.RegisterSoftbusListener(listener, sessionName, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_ADAPTER_REGISTER_SOFTBUS_LISTENER_FAIL, actual); +} + +/** + * @tc.name: UnRegisterSoftbusListener_001 + * @tc.desc: Verify the UnRegisterSoftbusListener function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, UnRegisterSoftbusListener_001, TestSize.Level1) +{ + std::string sessionName = "hello"; + std::string peerDevId = "world"; + + int32_t actual = softbusAdapter.UnRegisterSoftbusListener(sessionName, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: CreateSoftbusSessionServer_001 + * @tc.desc: Verify the CreateSoftbusSessionServer function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, CreateSoftbusSessionServer_001, TestSize.Level1) +{ + std::string pkgname = "hello"; + std::string sessionName = "world"; + std::string peerDevId = "world"; + + softbusAdapter.mapSessionSet_[sessionName].insert(peerDevId); + int32_t actual = softbusAdapter.CreateSoftbusSessionServer(pkgname, sessionName, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: RemoveSoftbusSessionServer_001 + * @tc.desc: Verify the RemoveSoftbusSessionServer function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, RemoveSoftbusSessionServer_001, TestSize.Level1) +{ + std::string pkgname = "hello"; + std::string sessionName = "world"; + std::string peerDevId = "world"; + + int32_t actual = softbusAdapter.RemoveSoftbusSessionServer(pkgname, sessionName, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ILLEGAL_OPERATION, actual); +} + +/** + * @tc.name: RemoveSoftbusSessionServer_002 + * @tc.desc: Verify the RemoveSoftbusSessionServer function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, RemoveSoftbusSessionServer_002, TestSize.Level1) +{ + std::string pkgname = "hello"; + std::string sessionName = "world"; + std::string peerDevId = "world"; + + softbusAdapter.mapSessionSet_[sessionName].insert(peerDevId); + int32_t actual = softbusAdapter.RemoveSoftbusSessionServer(pkgname, sessionName, peerDevId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: OpenSoftbusSession_001 + * @tc.desc: Verify the OpenSoftbusSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, OpenSoftbusSession_001, TestSize.Level1) +{ + std::string mySessionName = DATA_SESSION_NAME; + std::string peerSessionName = "world"; + std::string peerDevId = "world"; + + int32_t actual = softbusAdapter.OpenSoftbusSession(mySessionName, peerSessionName, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL, actual); +} + +/** + * @tc.name: OpenSoftbusSession_002 + * @tc.desc: Verify the OpenSoftbusSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, OpenSoftbusSession_002, TestSize.Level1) +{ + std::string mySessionName = "hello"; + std::string peerSessionName = "world"; + std::string peerDevId = "world"; + + int32_t actual = softbusAdapter.OpenSoftbusSession(mySessionName, peerSessionName, peerDevId); + + EXPECT_EQ(ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL, actual); +} + +/** + * @tc.name: CloseSoftbusSession_001 + * @tc.desc: Verify the CloseSoftbusSession function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, CloseSoftbusSession_001, TestSize.Level1) +{ + int32_t sessionId = 0; + + int32_t actual = softbusAdapter.CloseSoftbusSession(sessionId); + + EXPECT_EQ(DH_SUCCESS, actual); +} + +/** + * @tc.name: SendSoftbusBytes_001 + * @tc.desc: Verify the SendSoftbusBytes function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, SendSoftbusBytes_001, TestSize.Level1) +{ + int32_t sessionId = 0; + void *data = nullptr; + int32_t dataLen = 0; + + int32_t actual = softbusAdapter.SendSoftbusBytes(sessionId, data, dataLen); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ERROR, actual); +} + +/** + * @tc.name: SendSoftbusStream_001 + * @tc.desc: Verify the SendSoftbusStream function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, SendSoftbusStream_001, TestSize.Level1) +{ + int32_t sessionId = 0; + StreamData *data = nullptr; + StreamData *ext = nullptr; + StreamFrameInfo *param = nullptr; + + int32_t actual = softbusAdapter.SendSoftbusStream(sessionId, data, ext, param); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ERROR, actual); +} + +/** + * @tc.name: GetSoftbusListener_001 + * @tc.desc: Verify the GetSoftbusListener function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, GetSoftbusListener_001, TestSize.Level1) +{ + int32_t sessionId = 0; + + std::shared_ptr actual = softbusAdapter.GetSoftbusListenerById(sessionId); + + EXPECT_EQ(nullptr, actual); +} + +/** + * @tc.name: GetSoftbusListener_002 + * @tc.desc: Verify the GetSoftbusListener function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, GetSoftbusListener_002, TestSize.Level1) +{ + int32_t sessionId = 0; + + SessionInfo sessionInfo; + sessionInfo.sessionName = "hello"; + sessionInfo.peerDevId = "world"; + softbusAdapter.mapSessionInfos_[sessionId] = sessionInfo; + std::shared_ptr listener = nullptr; + softbusAdapter.mapListeners_["hello_world"] = listener; + std::shared_ptr actual = softbusAdapter.GetSoftbusListenerById(sessionId); + + EXPECT_EQ(nullptr, actual); +} + +/** + * @tc.name: OnSoftbusSessionOpened_001 + * @tc.desc: Verify the OnSoftbusSessionOpened function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, OnSoftbusSessionOpened_001, TestSize.Level1) +{ + int32_t sessionId = 0; + int32_t result = 0; + + int32_t actual = softbusAdapter.OnSoftbusSessionOpened(sessionId, result); + + EXPECT_EQ(ERR_DH_SCREEN_TRANS_ERROR, actual); +} + +/** + * @tc.name: OnSoftbusSessionClosed_001 + * @tc.desc: Verify the OnSoftbusSessionClosed function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, OnSoftbusSessionClosed_001, TestSize.Level1) +{ + int32_t sessionId = 0; + + softbusAdapter.OnSoftbusSessionClosed(sessionId); +} + +/** + * @tc.name: OnSoftbusSessionClosed_002 + * @tc.desc: Verify the OnSoftbusSessionClosed function. + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(SoftbusAdapterTest, OnSoftbusSessionClosed_002, TestSize.Level1) +{ + int32_t sessionId = 0; + + SessionInfo sessionInfo; + sessionInfo.sessionName = "hello"; + sessionInfo.peerDevId = "world"; + softbusAdapter.mapSessionInfos_[sessionId] = sessionInfo; + std::shared_ptr listener = nullptr; + softbusAdapter.mapListeners_["hello_world"] = listener; + + softbusAdapter.OnSoftbusSessionClosed(sessionId); +} +} // DistributedHardware +} // OHOS \ No newline at end of file -- Gitee From 3d1a5a076b66af4b735743078c158845f46dd069 Mon Sep 17 00:00:00 2001 From: sxzheng96 Date: Wed, 9 Mar 2022 15:48:45 +0800 Subject: [PATCH 2/2] modify ci problem --- common/src/dscreen_util.cpp | 2 +- .../screenservice/sourceservice/dscreenmgr/src/dscreen.cpp | 1 - .../dscreenservice/src/dscreen_source_service.cpp | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/src/dscreen_util.cpp b/common/src/dscreen_util.cpp index f404d41d..95ba2b78 100644 --- a/common/src/dscreen_util.cpp +++ b/common/src/dscreen_util.cpp @@ -72,7 +72,6 @@ std::string GetRandomID() std::string GetAnonyString(const std::string &value) { constexpr size_t INT32_SHORT_ID_LENGTH = 20; - constexpr size_t INT32_PLAINTEXT_LENGTH = 4; constexpr size_t INT32_MIN_ID_LENGTH = 3; std::string res; std::string tmpStr("******"); @@ -86,6 +85,7 @@ std::string GetAnonyString(const std::string &value) res += tmpStr; res += value[strLen - 1]; } else { + constexpr size_t INT32_PLAINTEXT_LENGTH = 4; res.append(value, 0, INT32_PLAINTEXT_LENGTH); res += tmpStr; res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH); diff --git a/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp index 22bf467c..2986ad13 100644 --- a/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp +++ b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp @@ -209,7 +209,6 @@ void DScreen::HandleEnable(const std::string ¶m, const std::string &taskId) videoParam_->SetScreenWidth(attrJson[KEY_SCREEN_WIDTH]); videoParam_->SetScreenHeight(attrJson[KEY_SCREEN_HEIGHT]); - std::string codecTypeStr = attrJson[KEY_CODECTYPE]; videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_NV21); videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_H264); diff --git a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp index 68220f09..df6efc3e 100644 --- a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp +++ b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp @@ -101,8 +101,8 @@ int32_t DScreenSourceService::RegisterDistributedHardware(const std::string &dev DHLOGI("RegisterDistributedHardware"); std::string version = param.version; std::string attrs = param.attrs; - DHLOGD("enable distributedScreen. devId: %s, dhId: %s, reqId: %s, attrs: %s", - GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), attrs.c_str()); + DHLOGD("enable distributedScreen. devId: %s, dhId: %s, reqId: %s, attrs: %s, version: %s", + GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), reqId.c_str(), attrs.c_str(), version.c_str()); int ret = DScreenManager::GetInstance().EnableDistributedScreen(devId, dhId, attrs, reqId); if (ret != DH_SUCCESS) { DHLOGE("enable distributedScreen failed. devId: %s, dhId: %s, reqId: %s, attrs: %s", -- Gitee