From 275d1bf7310a68196baec6744806e06483482d56 Mon Sep 17 00:00:00 2001 From: kiran-bhupali Date: Fri, 16 Jul 2021 14:48:08 +0530 Subject: [PATCH] added medialibrary module Signed-off-by: s00428065 --- LICENSE | 177 +++ .../innerkitsimpl/media_library/BUILD.gn | 82 ++ .../media_library/include/media_file_utils.h | 44 + .../include/media_library_utils.h | 48 + .../media_library/src/album_asset.cpp | 65 ++ .../media_library/src/audio_asset.cpp | 40 + .../media_library/src/image_asset.cpp | 38 + .../media_library/src/media_asset.cpp | 141 +++ .../media_library/src/media_file_utils.cpp | 194 ++++ .../media_library/src/media_library.cpp | 519 +++++++++ .../media_library/src/media_library_utils.cpp | 49 + .../media_library/src/video_asset.cpp | 40 + .../innerkitsimpl/media_library/test/BUILD.gn | 21 + .../moduletest/cpp/medialibrary_test/BUILD.gn | 51 + .../inc/medialibrary_module_test.h | 41 + .../src/medialibrary_module_test.cpp | 861 ++++++++++++++ .../innerkitsimpl/medialibrary_proxy/BUILD.gn | 54 + .../include/media_lib_proxy.h | 78 ++ .../src/media_lib_proxy.cpp | 584 ++++++++++ .../medialibrary_service/BUILD.gn | 58 + .../include/media_lib_service.h | 80 ++ .../include/media_lib_service_stub.h | 124 ++ .../src/media_lib_service.cpp | 206 ++++ .../src/media_lib_service_stub.cpp | 479 ++++++++ .../innerkitsimpl/prebuilts/etcs/BUILD.gn | 25 + .../prebuilts/etcs/medialibrary_service.cfg | 14 + .../prebuilts/etcs/medialibrary_service.rc | 20 + .../medialibrary/src/album_asset_napi.cpp | 622 ++++++++++ .../medialibrary/src/audio_asset_napi.cpp | 288 +++++ .../medialibrary/src/image_asset_napi.cpp | 257 +++++ .../medialibrary/src/media_asset_napi.cpp | 1006 +++++++++++++++++ .../medialibrary/src/media_library_napi.cpp | 888 +++++++++++++++ .../src/native_module_ohos_medialibrary.cpp | 54 + .../medialibrary/src/video_asset_napi.cpp | 288 +++++ .../native/include/IMediaLibraryClient.h | 198 ++++ .../innerkits/native/include/album_asset.h | 50 + .../innerkits/native/include/audio_asset.h | 41 + .../innerkits/native/include/image_asset.h | 40 + .../innerkits/native/include/media_asset.h | 57 + .../native/include/media_lib_service_const.h | 142 +++ .../innerkits/native/include/media_library.h | 197 ++++ .../innerkits/native/include/media_log.h | 53 + .../innerkits/native/include/video_asset.h | 41 + .../native/test/media_library_test.cpp | 149 +++ .../@ohos.multimedia.medialibrary.d.ts | 363 ++++++ interfaces/kits/js/medialibrary/BUILD.gn | 59 + .../medialibrary/include/album_asset_napi.h | 86 ++ .../medialibrary/include/audio_asset_napi.h | 60 + .../medialibrary/include/image_asset_napi.h | 58 + .../medialibrary/include/media_asset_napi.h | 114 ++ .../medialibrary/include/media_library_napi.h | 83 ++ .../include/medialibrary_napi_utils.h | 102 ++ .../include/native_module_ohos_medialibrary.h | 27 + .../medialibrary/include/video_asset_napi.h | 60 + ohos.build | 47 + sa_profile/3007.xml | 28 + sa_profile/BUILD.gn | 20 + 57 files changed, 9611 insertions(+) create mode 100644 LICENSE create mode 100644 frameworks/innerkitsimpl/media_library/BUILD.gn create mode 100644 frameworks/innerkitsimpl/media_library/include/media_file_utils.h create mode 100644 frameworks/innerkitsimpl/media_library/include/media_library_utils.h create mode 100644 frameworks/innerkitsimpl/media_library/src/album_asset.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/audio_asset.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/image_asset.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/media_asset.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/media_file_utils.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/media_library.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/media_library_utils.cpp create mode 100644 frameworks/innerkitsimpl/media_library/src/video_asset.cpp create mode 100644 frameworks/innerkitsimpl/media_library/test/BUILD.gn create mode 100644 frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/BUILD.gn create mode 100644 frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/inc/medialibrary_module_test.h create mode 100644 frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/src/medialibrary_module_test.cpp create mode 100644 frameworks/innerkitsimpl/medialibrary_proxy/BUILD.gn create mode 100644 frameworks/innerkitsimpl/medialibrary_proxy/include/media_lib_proxy.h create mode 100644 frameworks/innerkitsimpl/medialibrary_proxy/src/media_lib_proxy.cpp create mode 100644 frameworks/innerkitsimpl/medialibrary_service/BUILD.gn create mode 100644 frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service.h create mode 100644 frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service_stub.h create mode 100644 frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service.cpp create mode 100644 frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service_stub.cpp create mode 100644 frameworks/innerkitsimpl/prebuilts/etcs/BUILD.gn create mode 100644 frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.cfg create mode 100644 frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.rc create mode 100644 frameworks/kitsimpl/medialibrary/src/album_asset_napi.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/audio_asset_napi.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/image_asset_napi.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/media_asset_napi.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/media_library_napi.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/native_module_ohos_medialibrary.cpp create mode 100644 frameworks/kitsimpl/medialibrary/src/video_asset_napi.cpp create mode 100644 interfaces/innerkits/native/include/IMediaLibraryClient.h create mode 100644 interfaces/innerkits/native/include/album_asset.h create mode 100644 interfaces/innerkits/native/include/audio_asset.h create mode 100644 interfaces/innerkits/native/include/image_asset.h create mode 100644 interfaces/innerkits/native/include/media_asset.h create mode 100644 interfaces/innerkits/native/include/media_lib_service_const.h create mode 100644 interfaces/innerkits/native/include/media_library.h create mode 100644 interfaces/innerkits/native/include/media_log.h create mode 100644 interfaces/innerkits/native/include/video_asset.h create mode 100644 interfaces/innerkits/native/test/media_library_test.cpp create mode 100644 interfaces/kits/js/medialibrary/@ohos.multimedia.medialibrary.d.ts create mode 100644 interfaces/kits/js/medialibrary/BUILD.gn create mode 100644 interfaces/kits/js/medialibrary/include/album_asset_napi.h create mode 100644 interfaces/kits/js/medialibrary/include/audio_asset_napi.h create mode 100644 interfaces/kits/js/medialibrary/include/image_asset_napi.h create mode 100644 interfaces/kits/js/medialibrary/include/media_asset_napi.h create mode 100644 interfaces/kits/js/medialibrary/include/media_library_napi.h create mode 100644 interfaces/kits/js/medialibrary/include/medialibrary_napi_utils.h create mode 100644 interfaces/kits/js/medialibrary/include/native_module_ohos_medialibrary.h create mode 100644 interfaces/kits/js/medialibrary/include/video_asset_napi.h create mode 100644 ohos.build create mode 100644 sa_profile/3007.xml create mode 100644 sa_profile/BUILD.gn diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..4947287f7b --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/frameworks/innerkitsimpl/media_library/BUILD.gn b/frameworks/innerkitsimpl/media_library/BUILD.gn new file mode 100644 index 0000000000..9501785b24 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/BUILD.gn @@ -0,0 +1,82 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +group("media_library_packages") { + deps = [ + ":media_library", + ] +} + +config("media_library_config") { + visibility = [ ":*" ] + + include_dirs = [ + "./", + "./include", + "//foundation/multimedia/medialibrary_standard/interfaces/innerkits/native/include", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + ] + + cflags = [ + "-Wall", + "-Werror", + ] +} + +ohos_source_set("media_library_source") { + sources = [ + "src/album_asset.cpp", + "src/audio_asset.cpp", + "src/image_asset.cpp", + "src/media_asset.cpp", + "src/media_file_utils.cpp", + "src/media_library.cpp", + "src/media_library_utils.cpp", + "src/video_asset.cpp", + ] + + configs = [ ":media_library_config" ] +} + +ohos_shared_library("media_library") { + install_enable = true + + deps = [ + ":media_library_source", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + ] + + part_name = "multimedia_media_library_standard" + subsystem_name = "multimedia" +} + +ohos_source_set("media_library_test_source") { + sources = [ "//foundation/multimedia/medialibrary_standard/interfaces/innerkits/native/test/media_library_test.cpp" ] + + configs = [ ":media_library_config" ] +} + +ohos_executable("media_library_test") { + install_enable = true + + deps = [ + ":media_library", + ":media_library_test_source", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + ] + + part_name = "multimedia_media_library_standard" + subsystem_name = "multimedia" +} diff --git a/frameworks/innerkitsimpl/media_library/include/media_file_utils.h b/frameworks/innerkitsimpl/media_library/include/media_file_utils.h new file mode 100644 index 0000000000..79b62a950d --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/include/media_file_utils.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_FILE_UTILS_H +#define MEDIA_FILE_UTILS_H + +#include + +namespace OHOS { +namespace Media { +/** + * @brief Utility class for file operations + * + * @since 1.0 + * @version 1.0 + */ +class MediaFileUtils { +public: + static bool IsFileExists(const std::string& fileName); + static bool CreateFile(const std::string& fileName); + static bool DeleteFile(const std::string& fileName); + static bool DeleteDir(const std::string& dirName); + static std::string GetFilename(const std::string& filePath); + static bool IsDirectory(const std::string& dirName); + static bool MoveFile(const std::string& oldPath, const std::string& newPath); + static bool CopyFile(const std::string& filePath, const std::string& newPath); + static bool RenameDir(const std::string& oldPath, const std::string& newPath); + static bool CreateDirectory(const std::string& dirPath); +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_FILE_UTILS_H diff --git a/frameworks/innerkitsimpl/media_library/include/media_library_utils.h b/frameworks/innerkitsimpl/media_library/include/media_library_utils.h new file mode 100644 index 0000000000..f501904174 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/include/media_library_utils.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIBRARY_UTILS_H +#define MEDIA_LIBRARY_UTILS_H + +#include +#include "album_asset.h" +#include "audio_asset.h" +#include "image_asset.h" +#include "media_asset.h" +#include "video_asset.h" + +namespace OHOS { +namespace Media { +/** + * @brief Utility class for media library + * + * @since 1.0 + * @version 1.0 + */ +class MediaLibraryUtils { +public: + // Static variable to save the media type request by application + static MediaType requestedMediaType; + // Declaration of thread condition variable and mutes + static pthread_mutex_t mutexLock; + + static std::vector>& GetAudioAssetsInternal(); + static std::vector>& GetImageAssetsInternal(); + static std::vector>& GetMediaAssetsInternal(); + static std::vector>& GetVideoAssetsInternal(); +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_LIBRARY_UTILS_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/media_library/src/album_asset.cpp b/frameworks/innerkitsimpl/media_library/src/album_asset.cpp new file mode 100644 index 0000000000..3aa3fea249 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/album_asset.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "album_asset.h" +#include "media_file_utils.h" +#include "media_log.h" + +using namespace std; + +namespace OHOS { +namespace Media { +AlbumAsset::AlbumAsset() +{ + albumId_ = DEFAULT_ALBUM_ID; + albumName_ = DEFAULT_ALBUM_NAME; +} + +AlbumAsset::~AlbumAsset() = default; + +bool AlbumAsset::CreateAlbumAsset() +{ + string albumUri = ROOT_MEDIA_DIR + SLASH_CHAR + albumName_; + if (!(MediaFileUtils::IsDirectory(albumUri))) { + return MediaFileUtils::CreateDirectory(albumUri); + } else { + MEDIA_ERR_LOG("Cannot create album that already exists"); + return false; + } +} + +bool AlbumAsset::DeleteAlbumAsset(const string &albumUri) +{ + return MediaFileUtils::DeleteDir(albumUri); +} + +bool AlbumAsset::ModifyAlbumAsset(const AlbumAsset &albumAsset, const string &albumUri) +{ + string newAlbumUri; + string oldAlbumUri; + size_t slashIndex; + bool errCode = false; + + oldAlbumUri = albumUri; + slashIndex = albumUri.rfind("/"); + if (slashIndex != string::npos) { + newAlbumUri = albumUri.substr(0, slashIndex) + SLASH_CHAR + albumName_; + errCode = MediaFileUtils::RenameDir(oldAlbumUri, newAlbumUri); + } + + return errCode; +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/audio_asset.cpp b/frameworks/innerkitsimpl/media_library/src/audio_asset.cpp new file mode 100644 index 0000000000..1a8d8b6e4c --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/audio_asset.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_asset.h" + +using namespace std; + +namespace AudioAssetConstants { + const int32_t DEFAULT_AUDIO_DURATION = 0; + const string DEFAULT_AUDIO_TITLE = "Unknown"; + const string DEFAULT_AUDIO_ARTIST = "Unknown"; + const string DEFAULT_AUDIO_MIME_TYPE = "audio/*"; +} + +namespace OHOS { +namespace Media { +AudioAsset::AudioAsset() +{ + duration_ = AudioAssetConstants::DEFAULT_AUDIO_DURATION; + title_ = AudioAssetConstants::DEFAULT_AUDIO_TITLE; + artist_ = AudioAssetConstants::DEFAULT_AUDIO_ARTIST; + mimeType_ = AudioAssetConstants::DEFAULT_AUDIO_MIME_TYPE; + mediaType_ = MEDIA_TYPE_AUDIO; +} + +AudioAsset::~AudioAsset() = default; +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/image_asset.cpp b/frameworks/innerkitsimpl/media_library/src/image_asset.cpp new file mode 100644 index 0000000000..76e6cbafa4 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/image_asset.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "image_asset.h" + +using namespace std; + +namespace ImageAssetConstants { + const int32_t DEFAULT_IMAGE_WIDTH = 1280; + const int32_t DEFAULT_IMAGE_HEIGHT = 720; + const string DEFAULT_IMAGE_MIME_TYPE = "image/*"; +} + +namespace OHOS { +namespace Media { +ImageAsset::ImageAsset() +{ + width_ = ImageAssetConstants::DEFAULT_IMAGE_WIDTH; + height_ = ImageAssetConstants::DEFAULT_IMAGE_HEIGHT; + mimeType_ = ImageAssetConstants::DEFAULT_IMAGE_MIME_TYPE; + mediaType_ = MEDIA_TYPE_IMAGE; +} + +ImageAsset::~ImageAsset() = default; +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/media_asset.cpp b/frameworks/innerkitsimpl/media_library/src/media_asset.cpp new file mode 100644 index 0000000000..e4fa12efd9 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/media_asset.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_asset.h" + +#include "media_file_utils.h" +#include "media_lib_service_const.h" +#include "media_log.h" + +using namespace std; + +namespace OHOS { +namespace Media { +MediaAsset::MediaAsset() +{ + id_ = DEFAULT_MEDIA_ID; + albumId_ = DEFAULT_ALBUM_ID; + albumName_ = DEFAULT_ALBUM_NAME; + size_ = DEFAULT_MEDIA_SIZE; + uri_ = DEFAULT_MEDIA_URI; + mediaType_ = DEFAULT_MEDIA_TYPE; + name_ = DEFAULT_MEDIA_NAME; + dateAdded_ = DEFAULT_MEDIA_DATE_ADDED; + dateModified_ = DEFAULT_MEDIA_DATE_MODIFIED; +} + +MediaAsset::~MediaAsset() = default; + +MediaType MediaAsset::GetMediaType(const std::string &filePath) +{ + MediaType mediaType = MEDIA_TYPE_FILE; + + if (filePath.size() == 0) { + return MEDIA_TYPE_DEFAULT; + } + + size_t dotIndex = filePath.rfind(DOT_CHAR); + if (dotIndex != string::npos) { + string extension = filePath.substr(dotIndex + 1, filePath.length() - dotIndex); + if (SUPPORTED_AUDIO_FORMATS_SET.find(extension) != SUPPORTED_AUDIO_FORMATS_SET.end()) { + mediaType = MEDIA_TYPE_AUDIO; + } else if (SUPPORTED_VIDEO_FORMATS_SET.find(extension) + != SUPPORTED_VIDEO_FORMATS_SET.end()) { + mediaType = MEDIA_TYPE_VIDEO; + } else if (SUPPORTED_IMAGE_FORMATS_SET.find(extension) + != SUPPORTED_IMAGE_FORMATS_SET.end()) { + mediaType = MEDIA_TYPE_IMAGE; + } else { + mediaType = MEDIA_TYPE_FILE; + } + } + + return mediaType; +} + +bool MediaAsset::CreateMediaAsset(AssetType assetType) +{ + bool errCode = false; + MediaType mediaType; + string dirPath = ROOT_MEDIA_DIR + SLASH_CHAR + albumName_ + + SLASH_CHAR; + + uri_ = ROOT_MEDIA_DIR + SLASH_CHAR + name_; + + if (!(name_.empty())) { + mediaType = GetMediaType(name_); + if ((assetType == ASSET_AUDIO && mediaType == MEDIA_TYPE_AUDIO) || + (assetType == ASSET_VIDEO && mediaType == MEDIA_TYPE_VIDEO) || + (assetType == ASSET_IMAGE && mediaType == MEDIA_TYPE_IMAGE)) { + errCode = true; + if (!(albumName_.empty())) { + uri_ = dirPath + name_; + if (!(MediaFileUtils::IsDirectory(dirPath))) { + errCode = MediaFileUtils::CreateDirectory(dirPath); + } + } + + if (errCode) { + errCode = MediaFileUtils::CreateFile(uri_); + } + } + } + + return errCode; +} + +bool MediaAsset::DeleteMediaAsset() +{ + return MediaFileUtils::DeleteFile(uri_); +} + +bool MediaAsset::ModifyMediaAsset(const MediaAsset &mediaAsset) +{ + string fileExtnSrc = ""; + string fileExtnDst = ""; + bool errCode = false; + size_t dotIndexDst = name_.find("."); + size_t dotIndexSrc = mediaAsset.name_.find("."); + + if (uri_.empty()) { + MEDIA_ERR_LOG("MediaAsset ModifyMediaAsset:Uri empty"); + return false; + } + + if (dotIndexDst != string::npos) { + if (name_.size() > dotIndexDst) { + fileExtnDst = name_.substr(dotIndexDst); + } + } + + if (dotIndexSrc != string::npos) { + if (mediaAsset.name_.size() > dotIndexSrc) { + fileExtnSrc = mediaAsset.name_.substr(dotIndexSrc); + } + } + + if (fileExtnSrc == fileExtnDst) { + errCode = MediaFileUtils::MoveFile(mediaAsset.uri_, uri_); + } + + return errCode; +} + +bool MediaAsset::CopyMediaAsset(const MediaAsset &mediaAsset) +{ + return MediaFileUtils::CopyFile(mediaAsset.uri_, uri_); +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/media_file_utils.cpp b/frameworks/innerkitsimpl/media_library/src/media_file_utils.cpp new file mode 100644 index 0000000000..6375b18156 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/media_file_utils.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_file_utils.h" +#include "media_lib_service_const.h" +#include "media_log.h" + +#include +#include +#include +#include +#include + +using namespace std; + +namespace OHOS { +namespace Media { +int UnlinkCb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) +{ + int errRet = remove(fpath); + if (errRet) { + perror(fpath); + } + + return errRet; +} + +int RemoveDirectory(const string &path) +{ + int errCode; + char *dirPath = const_cast(path.c_str()); + + errCode = nftw(dirPath, UnlinkCb, OPEN_FDS, FTW_DEPTH | FTW_PHYS); + return errCode; +} + +bool MediaFileUtils::CreateDirectory(const string& dirPath) +{ + string subStr; + string segment; + + /* Create directory and its sub directories if does not exist + * take each string after '/' create directory if does not exist. + * Created directory will be the base path for the next sub directory. + */ + + stringstream folderStream(dirPath.c_str()); + while (std::getline(folderStream, segment, '/')) { + if (segment == "") // skip the first "/" in case of "/data/media" + continue; + + subStr = subStr + SLASH_CHAR + segment; + if (!IsDirectory(subStr)) { + mkdir(subStr.c_str(), S_IRWXG); + } + } + + return true; +} + +bool MediaFileUtils::IsFileExists(const string& fileName) +{ + struct stat statInfo {}; + + return ((stat(fileName.c_str(), &statInfo)) == SUCCESS); +} + +string MediaFileUtils::GetFilename(const string& filePath) +{ + string fileName = ""; + + if (!(filePath.empty())) { + size_t slashIndex = filePath.rfind("/"); + if (slashIndex != string::npos) { + if (filePath.size() > slashIndex) { + fileName = filePath.substr(slashIndex + 1, filePath.length() - slashIndex); + } + } + } + + return fileName; +} + +bool MediaFileUtils::IsDirectory(const string& dirName) +{ + struct stat statInfo {}; + if (stat(dirName.c_str(), &statInfo) == SUCCESS) { + if (statInfo.st_mode & S_IFDIR) { + return true; + } + } + + return false; +} + +bool MediaFileUtils::CreateFile(const string& filePath) +{ + if (filePath.empty()) { + return false; + } + + if (IsFileExists(filePath)) { + return false; + } + + ofstream file(filePath); + if (!file) { + MEDIA_ERR_LOG("Output file path could not be created"); + return false; + } + file.close(); + + return true; +} + +bool MediaFileUtils::DeleteFile(const string& fileName) +{ + return (remove(fileName.c_str()) == SUCCESS); +} + +bool MediaFileUtils::DeleteDir(const std::string& dirName) +{ + bool errRet = false; + + if (IsDirectory(dirName)) { + errRet = (RemoveDirectory(dirName) == SUCCESS); + } + + return errRet; +} + +bool MediaFileUtils::MoveFile(const string& oldPath, const string& newPath) +{ + bool errRet = false; + + if (IsFileExists(oldPath) && !IsFileExists(newPath)) { + errRet = (rename(oldPath.c_str(), newPath.c_str()) == SUCCESS); + } + + return errRet; +} + +bool MediaFileUtils::CopyFile(const string &filePath, const string &newPath) +{ + string newPathCorrected; + bool errCode = false; + + if (!(newPath.empty()) && !(filePath.empty())) { + newPathCorrected = newPath + "/" + GetFilename(filePath); + } else { + MEDIA_ERR_LOG("Src filepath or dest filePath value cannot be empty"); + return false; + } + + if (IsFileExists(filePath) == true && !IsFileExists(newPathCorrected)) { + errCode = true; // set to create file if directory exists + if (!(IsDirectory(newPath))) { + errCode = CreateDirectory(newPath); + } + if (errCode == true) { + ifstream src(filePath, ios::binary); + ofstream dst(newPathCorrected, ios::binary); + + dst << src.rdbuf(); + } + } + + return errCode; +} + +bool MediaFileUtils::RenameDir(const string& oldPath, const string& newPath) +{ + bool errRet = false; + + if (IsDirectory(oldPath)) { + errRet = (rename(oldPath.c_str(), newPath.c_str()) == SUCCESS); + } + + return errRet; +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/media_library.cpp b/frameworks/innerkitsimpl/media_library/src/media_library.cpp new file mode 100644 index 0000000000..69a10d5894 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/media_library.cpp @@ -0,0 +1,519 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_library.h" + +#include +#include +#include +#include +#include +#include + +#include "media_lib_service_const.h" +#include "media_library_utils.h" +#include "media_log.h" + +using namespace std; + +namespace OHOS { +namespace Media { +#define CHK_NULL_RETURN(ptr) \ +do { \ + if ((ptr) == nullptr) { \ + return MEDIA_SCAN_FAIL; \ + } \ +} while (0) + +#define CHK_NULL_RETURN_ERROR(ptr, ret) \ +do { \ + if ((ptr) == nullptr) { \ + return ret; \ + } \ +} while (0) + +MediaLibrary::MediaLibrary() {} + +MediaLibrary::~MediaLibrary() = default; + +unique_ptr MediaLibrary::GetMediaLibraryInstance() +{ + return make_unique(); +} + +string GetNameFromUri(const string &uri) +{ + string fileName = DEFAULT_MEDIA_NAME; + + size_t slashIndex = uri.rfind(SLASH_CHAR); + if (slashIndex != string::npos) { + if (uri.size() > slashIndex) { + fileName = uri.substr(slashIndex + 1, uri.length() - slashIndex); + } + } + + return fileName; +} + +unique_ptr UpdateMediaData(const string &assetUri, const struct stat &statInfo) +{ + if (assetUri.empty()) { + MEDIA_ERR_LOG("Uri is empty!"); + return nullptr; + } + + unique_ptr mediaAsset = make_unique(); + mediaAsset->uri_ = assetUri; + mediaAsset->name_ = GetNameFromUri(assetUri); + mediaAsset->mediaType_ = MEDIA_TYPE_FILE; + mediaAsset->size_ = statInfo.st_size; + mediaAsset->dateModified_ = statInfo.st_mtime * MILLISECONDS; + mediaAsset->dateAdded_ = statInfo.st_ctime * MILLISECONDS; + + return mediaAsset; +} + +unique_ptr UpdateAudioData(const string &assetUri, const struct stat &statInfo) +{ + if (assetUri.empty()) { + MEDIA_ERR_LOG("Uri is empty!"); + return nullptr; + } + + unique_ptr audioAsset = make_unique(); + audioAsset->uri_ = assetUri; + audioAsset->name_ = GetNameFromUri(assetUri); + audioAsset->mediaType_ = MEDIA_TYPE_AUDIO; + audioAsset->size_ = statInfo.st_size; + audioAsset->dateModified_ = statInfo.st_mtime * MILLISECONDS; + audioAsset->dateAdded_ = statInfo.st_ctime * MILLISECONDS; + + return audioAsset; +} + +unique_ptr UpdateVideoData(const string &assetUri, const struct stat &statInfo) +{ + if (assetUri.empty()) { + MEDIA_ERR_LOG("Uri is empty!"); + return nullptr; + } + + unique_ptr videoAsset = make_unique(); + videoAsset->uri_ = assetUri; + videoAsset->name_ = GetNameFromUri(assetUri); + videoAsset->mediaType_ = MEDIA_TYPE_VIDEO; + videoAsset->size_ = statInfo.st_size; + videoAsset->dateModified_ = statInfo.st_mtime * MILLISECONDS; + videoAsset->dateAdded_ = statInfo.st_ctime * MILLISECONDS; + + return videoAsset; +} + +unique_ptr UpdateImageData(const string &assetUri, const struct stat &statInfo) +{ + if (assetUri.empty()) { + MEDIA_ERR_LOG("Uri is empty!"); + return nullptr; + } + + unique_ptr imageAsset = make_unique(); + imageAsset->uri_ = assetUri; + imageAsset->name_ = GetNameFromUri(assetUri); + imageAsset->mediaType_ = MEDIA_TYPE_IMAGE; + imageAsset->size_ = statInfo.st_size; + imageAsset->dateModified_ = statInfo.st_mtime * MILLISECONDS; + imageAsset->dateAdded_ = statInfo.st_ctime * MILLISECONDS; + + return imageAsset; +} + +void ScanMediaAssetInfo(MediaType mediaType, const string &path, const struct stat *statInfo) +{ + switch (mediaType) { + case MEDIA_TYPE_AUDIO: { + if (MediaLibraryUtils::requestedMediaType == MEDIA_TYPE_AUDIO) { + unique_ptr audioAsset = UpdateAudioData(path, *statInfo); + if (audioAsset != nullptr) { + vector> &audioAssetList + = MediaLibraryUtils::GetAudioAssetsInternal(); + audioAsset->id_ = (int32_t)audioAssetList.size(); + audioAssetList.push_back(std::move(audioAsset)); + } + } + break; + } + case MEDIA_TYPE_VIDEO: { + if (MediaLibraryUtils::requestedMediaType == MEDIA_TYPE_VIDEO) { + unique_ptr videoAsset = UpdateVideoData(path, *statInfo); + if (videoAsset != nullptr) { + vector> &videoAssetList + = MediaLibraryUtils::GetVideoAssetsInternal(); + videoAsset->id_ = (int32_t)videoAssetList.size(); + videoAssetList.push_back(std::move(videoAsset)); + } + } + break; + } + case MEDIA_TYPE_IMAGE: { + if (MediaLibraryUtils::requestedMediaType == MEDIA_TYPE_IMAGE) { + unique_ptr imageAsset = UpdateImageData(path, *statInfo); + if (imageAsset != nullptr) { + vector> &imageAssetList + = MediaLibraryUtils::GetImageAssetsInternal(); + imageAsset->id_ = (int32_t)imageAssetList.size(); + imageAssetList.push_back(std::move(imageAsset)); + } + } + break; + } + default: + MEDIA_ERR_LOG("ScanMediaAssetInfo :Unknown media type"); + break; + } + + return; +} + +int ScanCallback(const char *path, const struct stat *statInfo, int typeFlag, struct FTW *ftwInfo) +{ + if ((path == nullptr) || (statInfo == nullptr)) { + MEDIA_ERR_LOG("Invalid arguments!"); + return 0; + } + + if (typeFlag == FTW_F) { + MediaType mediaType = MediaAsset::GetMediaType(path); + + // Add all files in media assets vector + if (MediaLibraryUtils::requestedMediaType == MEDIA_TYPE_MEDIA) { + unique_ptr mediaAsset = UpdateMediaData(path, *statInfo); + if (mediaAsset != nullptr) { + vector> &mediaAssetList + = MediaLibraryUtils::GetMediaAssetsInternal(); + mediaAsset->id_ = (int32_t)mediaAssetList.size(); + mediaAsset->mediaType_ = mediaType; + mediaAssetList.push_back(std::move(mediaAsset)); + } + } + ScanMediaAssetInfo(mediaType, string(path), statInfo); + } + + return 0; +} + +void ClearAssets() +{ + vector> &imageAssets + = MediaLibraryUtils::GetImageAssetsInternal(); + imageAssets.clear(); + + vector> &videoAssets + = MediaLibraryUtils::GetVideoAssetsInternal(); + videoAssets.clear(); + + vector> &audioAssets + = MediaLibraryUtils::GetAudioAssetsInternal(); + audioAssets.clear(); + + vector> &mediaAssets + = MediaLibraryUtils::GetMediaAssetsInternal(); + mediaAssets.clear(); +} + +int32_t ScanDir(const string &scanDir) +{ + int32_t ret = MEDIA_SCAN_SUCCESS; + // By default use /data/media as scan directory + string scanUri = ROOT_MEDIA_DIR; + + if (!scanDir.empty()) { + scanUri = ROOT_MEDIA_DIR + SLASH_CHAR + scanDir; + } + + // Clear all asset vectors before scanning + ClearAssets(); + + ret = nftw(scanUri.c_str(), ScanCallback, OPEN_FDS, FTW_PHYS); + if (ret < 0) { + ret = MEDIA_SCAN_FAIL; + } + + return ret; +} + +vector GetSubDirectories(string rootDir) +{ + DIR *dirPath = nullptr; + struct dirent *ent = nullptr; + vector dirList; + string scanDir = ROOT_MEDIA_DIR; + + if (!rootDir.empty()) { + scanDir = ROOT_MEDIA_DIR + SLASH_CHAR + rootDir; + } + + if ((dirPath = opendir(scanDir.c_str())) != nullptr) { + while ((ent = readdir(dirPath)) != nullptr) { + if (ent->d_type == DT_DIR) { + string currentDir("."); + string parentDir(".."); + if ((currentDir.compare(ent->d_name) != 0) + && (parentDir.compare(ent->d_name) != 0)) { + string dirPath = scanDir + SLASH_CHAR + ent->d_name; + dirList.push_back(dirPath); + } + } + } + closedir(dirPath); + } + + return dirList; +} + +int32_t ScanAlbums(const unique_ptr &albumAsset, string albumDir, int32_t requestedMediaType) +{ + int32_t ret = MEDIA_SCAN_FAIL; + + if (albumDir.empty()) { + return ret; + } + + DIR *dirPath = nullptr; + struct dirent *ent = nullptr; + if ((dirPath = opendir(albumDir.c_str())) != nullptr) { + size_t slashIndex = albumDir.rfind(SLASH_CHAR); + if (slashIndex != string::npos) { + if (albumDir.size() > slashIndex) { + albumAsset->albumName_ = albumDir.substr(slashIndex + 1, albumDir.length() - slashIndex); + } + } + + while ((ent = readdir(dirPath)) != nullptr) { + if (ent->d_type == DT_REG) { + string fileUri = albumDir + SLASH_CHAR + ent->d_name; + struct stat statInfo {}; + if (stat(fileUri.c_str(), &statInfo) != 0) { + MEDIA_ERR_LOG("No stat info"); + continue; + } + + MediaType mediaType = MediaAsset::GetMediaType(fileUri); + if ((mediaType == MEDIA_TYPE_IMAGE) && + (requestedMediaType == MEDIA_TYPE_IMAGE)) { + unique_ptr imageAsset = UpdateImageData(fileUri, statInfo); + imageAsset->id_ = (int32_t)albumAsset->imageAssetList_.size(); + albumAsset->imageAssetList_.push_back(std::move(imageAsset)); + } else if ((mediaType == MEDIA_TYPE_VIDEO) && + (requestedMediaType == MEDIA_TYPE_VIDEO)) { + unique_ptr videoAsset = UpdateVideoData(fileUri, statInfo); + videoAsset->id_ = (int32_t)albumAsset->videoAssetList_.size(); + albumAsset->videoAssetList_.push_back(std::move(videoAsset)); + } + } + } + closedir(dirPath); + ret = MEDIA_SCAN_SUCCESS; + } + + return ret; +} + +template +void SortMediaAssetsByDateAdded(vector> &mediaAssetList) +{ + sort(mediaAssetList.begin(), mediaAssetList.end(), + [](const unique_ptr &mediaAsset1, const unique_ptr &mediaAsset2) { + return (mediaAsset1->dateAdded_ > mediaAsset2->dateAdded_); + }); +} + +vector> MediaLibrary::GetMediaAssets(string selection, + vector selectionArgs) +{ + MediaLibraryUtils::requestedMediaType = MEDIA_TYPE_MEDIA; + vector> mediaAssets; + + pthread_mutex_lock(&(MediaLibraryUtils::mutexLock)); + + if (ScanDir(selection) == MEDIA_SCAN_SUCCESS) { + vector> &mediaAssetsInternal + = MediaLibraryUtils::GetMediaAssetsInternal(); + for (size_t i = 0; i < mediaAssetsInternal.size(); i++) { + mediaAssets.push_back(std::move(mediaAssetsInternal[i])); + } + mediaAssetsInternal.clear(); + + // Sort the Media Asset Vector based on Created Date + SortMediaAssetsByDateAdded(mediaAssets); + } + pthread_mutex_unlock(&(MediaLibraryUtils::mutexLock)); + + return mediaAssets; +} + +vector> MediaLibrary::GetAlbumAssets(string selection, + vector selectionArgs, + int32_t requestedMediaType) +{ + vector> albumAssets; + vector albumSubDirList = GetSubDirectories(selection); + + for (size_t i = 0; i < albumSubDirList.size(); i++) { + unique_ptr albumAsset = make_unique(); + if (ScanAlbums(albumAsset, albumSubDirList[i], requestedMediaType) == MEDIA_SCAN_SUCCESS) { + if (((requestedMediaType == MEDIA_TYPE_IMAGE) && (albumAsset->imageAssetList_.size() == 0)) || + ((requestedMediaType == MEDIA_TYPE_VIDEO) && (albumAsset->videoAssetList_.size() == 0))) { + continue; + } + // Sort Album's Image Asset List + SortMediaAssetsByDateAdded(albumAsset->imageAssetList_); + + // Sort Album's Video Asset List + SortMediaAssetsByDateAdded(albumAsset->videoAssetList_); + albumAssets.push_back(std::move(albumAsset)); + } else { + MEDIA_ERR_LOG("MediaLibrary: Scan albums failed, return empty"); + break; + } + } + + return albumAssets; +} + +vector> MediaLibrary::GetAudioAssets(string selection, + vector selectionArgs) +{ + MediaLibraryUtils::requestedMediaType = MEDIA_TYPE_AUDIO; + vector> audioAssets; + + pthread_mutex_lock(&(MediaLibraryUtils::mutexLock)); + + if (ScanDir(selection) == MEDIA_SCAN_SUCCESS) { + vector> &audioAssetsInternal + = MediaLibraryUtils::GetAudioAssetsInternal(); + for (size_t i = 0; i < audioAssetsInternal.size(); i++) { + audioAssets.push_back(std::move(audioAssetsInternal[i])); + } + audioAssetsInternal.clear(); + + // Sort the Audio Asset Vector based on Created Date + SortMediaAssetsByDateAdded(audioAssets); + } + pthread_mutex_unlock(&(MediaLibraryUtils::mutexLock)); + + return audioAssets; +} + +vector> MediaLibrary::GetVideoAssets(string selection, + vector selectionArgs) +{ + MediaLibraryUtils::requestedMediaType = MEDIA_TYPE_VIDEO; + vector> videoAssets; + + pthread_mutex_lock(&(MediaLibraryUtils::mutexLock)); + + if (ScanDir(selection) == MEDIA_SCAN_SUCCESS) { + vector> &videoAssetsInternal + = MediaLibraryUtils::GetVideoAssetsInternal(); + for (size_t i = 0; i < videoAssetsInternal.size(); i++) { + videoAssets.push_back(std::move(videoAssetsInternal[i])); + } + videoAssetsInternal.clear(); + + // Sort the Video Asset Vector based on Created Date + SortMediaAssetsByDateAdded(videoAssets); + } + pthread_mutex_unlock(&(MediaLibraryUtils::mutexLock)); + + return videoAssets; +} + +vector> MediaLibrary::GetImageAssets(string selection, + vector selectionArgs) +{ + MediaLibraryUtils::requestedMediaType = MEDIA_TYPE_IMAGE; + vector> imageAssets; + + pthread_mutex_lock(&(MediaLibraryUtils::mutexLock)); + + if (ScanDir(selection) == MEDIA_SCAN_SUCCESS) { + vector> &imageAssetsInternal + = MediaLibraryUtils::GetImageAssetsInternal(); + for (size_t i = 0; i < imageAssetsInternal.size(); i++) { + imageAssets.push_back(std::move(imageAssetsInternal[i])); + } + imageAssetsInternal.clear(); + + // Sort the Image Asset Vector based on Created Date + SortMediaAssetsByDateAdded(imageAssets); + } + pthread_mutex_unlock(&(MediaLibraryUtils::mutexLock)); + + return imageAssets; +} + +bool MediaLibrary::CreateMediaAsset(AssetType assetType, const MediaAsset& crtMediaAsset) +{ + MediaAsset *mediaAsset = (MediaAsset *)&crtMediaAsset; + + return mediaAsset->CreateMediaAsset(assetType); +} + +bool MediaLibrary::DeleteMediaAsset(AssetType assetType, const MediaAsset& delMediaAsset) +{ + MediaAsset *mediaAsset = (MediaAsset *)&delMediaAsset; + + return mediaAsset->DeleteMediaAsset(); +} + +bool MediaLibrary::ModifyMediaAsset(AssetType assetType, const MediaAsset& srcMediaAsset, + const MediaAsset &dstAsset) +{ + MediaAsset *dstMediaAsset = (MediaAsset *)&dstAsset; + + return dstMediaAsset->ModifyMediaAsset(srcMediaAsset); +} + +bool MediaLibrary::CopyMediaAsset(AssetType assetType, const MediaAsset& srcMediaAsset, + const MediaAsset& dstAsset) +{ + MediaAsset *dstMediaAsset = (MediaAsset *)&dstAsset; + + return dstMediaAsset->CopyMediaAsset(srcMediaAsset); +} + +bool MediaLibrary::CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset& albmAsset) +{ + AlbumAsset *albumAsset = (AlbumAsset *)&albmAsset; + + return albumAsset->CreateAlbumAsset(); +} + +bool MediaLibrary::DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset& albmAsset, const string &albumUri) +{ + AlbumAsset *albumAsset = (AlbumAsset *)&albmAsset; + + return albumAsset->DeleteAlbumAsset(albumUri); +} + +bool MediaLibrary::ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset& srcAlbumAsset, + const AlbumAsset &dstAlbAsset, const string &albumUri) +{ + AlbumAsset *dstAlbumAsset = (AlbumAsset *)&dstAlbAsset; + + return dstAlbumAsset->ModifyAlbumAsset(srcAlbumAsset, albumUri); +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/src/media_library_utils.cpp b/frameworks/innerkitsimpl/media_library/src/media_library_utils.cpp new file mode 100644 index 0000000000..c14dbb6103 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/media_library_utils.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_library_utils.h" + +using namespace std; + +namespace OHOS { +namespace Media { +MediaType MediaLibraryUtils::requestedMediaType = MEDIA_TYPE_DEFAULT; +pthread_mutex_t (MediaLibraryUtils::mutexLock) = PTHREAD_MUTEX_INITIALIZER; + +vector>& MediaLibraryUtils::GetAudioAssetsInternal() +{ + static vector> audioAsset; + return audioAsset; +} + +vector>& MediaLibraryUtils::GetImageAssetsInternal() +{ + static vector> imageAsset; + return imageAsset; +} + +vector>& MediaLibraryUtils::GetMediaAssetsInternal() +{ + static vector> mediaAsset; + return mediaAsset; +} + +vector>& MediaLibraryUtils::GetVideoAssetsInternal() +{ + static vector> videoAsset; + return videoAsset; +} +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/innerkitsimpl/media_library/src/video_asset.cpp b/frameworks/innerkitsimpl/media_library/src/video_asset.cpp new file mode 100644 index 0000000000..396688dda5 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/src/video_asset.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "video_asset.h" + +using namespace std; + +namespace VideoAssetConstants { + const int32_t DEFAULT_VIDEO_WIDTH = 1280; + const int32_t DEFAULT_VIDEO_HEIGHT = 720; + const int32_t DEFAULT_VIDEO_DURATION = 0; + const string DEFAULT_VIDEO_MIME_TYPE = "video/*"; +} + +namespace OHOS { +namespace Media { +VideoAsset::VideoAsset() +{ + width_ = VideoAssetConstants::DEFAULT_VIDEO_WIDTH; + height_ = VideoAssetConstants::DEFAULT_VIDEO_HEIGHT; + duration_ = VideoAssetConstants::DEFAULT_VIDEO_DURATION; + mimeType_ = VideoAssetConstants::DEFAULT_VIDEO_MIME_TYPE; + mediaType_ = MEDIA_TYPE_VIDEO; +} + +VideoAsset::~VideoAsset() = default; +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/media_library/test/BUILD.gn b/frameworks/innerkitsimpl/media_library/test/BUILD.gn new file mode 100644 index 0000000000..88c282a66d --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/test/BUILD.gn @@ -0,0 +1,21 @@ +# 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. + +group("medialib_module_test") { + testonly = true + + deps = [ + "moduletest/cpp/medialibrary_test:moduletest", + ] +} + diff --git a/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/BUILD.gn b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/BUILD.gn new file mode 100644 index 0000000000..e12c2cfb45 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/BUILD.gn @@ -0,0 +1,51 @@ +# 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") + +MEDIA_LIB_BASE_DIR = "//foundation/multimedia/medialibrary_standard" +MEDIA_LIB_INNERKITS_DIR = "$MEDIA_LIB_BASE_DIR/frameworks/innerkitsimpl" +MEDIA_LIB_TEST_DIR = "$MEDIA_LIB_INNERKITS_DIR/media_library/media_library/test/" + +module_output_path = "medialibrary/gtest" + +group("moduletest") { + testonly = true + + deps = [ + ":medialibrary_test", + ] +} + +ohos_moduletest("medialibrary_test") { + module_out_path = module_output_path + include_dirs = [ + "./inc", + "$MEDIA_LIB_BASE_DIR/interfaces/innerkits/native/include", + "$MEDIA_LIB_INNERKITS_DIR/media_library/include/", + "$MEDIA_LIB_TEST_DIR/moduletest/cpp/medialibrary_test/inc/", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include/", + "//utils/native/base/include" + ] + + sources = [ + "src/medialibrary_module_test.cpp" + ] + + deps = [ + "$MEDIA_LIB_INNERKITS_DIR/medialibrary_proxy:medialibrary_proxy", + "$MEDIA_LIB_INNERKITS_DIR/media_library:media_library", + "//utils/native/base:utils", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog" + ] +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/inc/medialibrary_module_test.h b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/inc/medialibrary_module_test.h new file mode 100644 index 0000000000..437bca9a07 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/inc/medialibrary_module_test.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIALIBRARY_MODULE_TEST_H +#define MEDIALIBRARY_MODULE_TEST_H + +#include "gtest/gtest.h" +#include "IMediaLibraryClient.h" +#include "media_library.h" + +namespace OHOS { +namespace Media { +class MediaLibraryModuleTest : public testing::Test { +public: + /* SetUpTestCase:The preset action of the test suite is executed before the first TestCase */ + static void SetUpTestCase(void); + + /* TearDownTestCase:The test suite cleanup action is executed after the last TestCase */ + static void TearDownTestCase(void); + + /* SetUp:Execute before each test case */ + void SetUp(); + + /* TearDown:Execute after each test case */ + void TearDown(); +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIALIBRARY_MODULE_TEST_H diff --git a/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/src/medialibrary_module_test.cpp b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/src/medialibrary_module_test.cpp new file mode 100644 index 0000000000..9b507d9649 --- /dev/null +++ b/frameworks/innerkitsimpl/media_library/test/moduletest/cpp/medialibrary_test/src/medialibrary_module_test.cpp @@ -0,0 +1,861 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "medialibrary_module_test.h" +#include "media_log.h" + +using namespace std; +using namespace testing::ext; + +namespace OHOS { +namespace Media { +IMediaLibraryClient* mediaLibClientInstance = nullptr; + +void MediaLibraryModuleTest::SetUpTestCase(void) {} +void MediaLibraryModuleTest::TearDownTestCase(void) {} + +/* SetUp:Execute before each test case */ +void MediaLibraryModuleTest::SetUp() +{ + mediaLibClientInstance = IMediaLibraryClient::GetMediaLibraryClientInstance(); +} + +void MediaLibraryModuleTest::TearDown(void) +{ + mediaLibClientInstance = nullptr; +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media audio asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_AUDIO; + mediaAsset.name_ = "test_001_audio.mp3"; + mediaAsset.albumName_ = "gtest/001/audio"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media audio asset in ROOT_DIR=/data/media directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_002, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_AUDIO; + + mediaAsset.name_ = "gtest_002_audio.mp3"; + mediaAsset.albumName_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} +/* + * Feature: MediaLibrary + * Function: GetAudioAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get audio assets prsent in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetAudioAssets_test_001, TestSize.Level1) +{ + vector> audioAssetList; + unsigned int size = 0; + string dirPath = "gtest/001/audio"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + audioAssetList = mediaLibClientInstance->GetAudioAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(audioAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetAudioAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get audio assets from ROOT_DIR=/data/media directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetAudioAssets_test_002, TestSize.Level1) +{ + vector> audioAssetList; + unsigned int size = 0; + string dirPath = ""; // ROOT_DIR + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + audioAssetList = mediaLibClientInstance->GetAudioAssets(dirPath, selectionArgs); + } + EXPECT_NE(audioAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media video asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_003, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_VIDEO; + + mediaAsset.name_ = "test_002_video.mp4"; + mediaAsset.albumName_ = "gtest/002/video"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media video sset in ROOT_DIR=/data/media directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_004, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_VIDEO; + + mediaAsset.name_ = "test_002_video.mp4"; + mediaAsset.albumName_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: GetVideoAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get video assets present in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetVideoAssets_test_001, TestSize.Level1) +{ + vector> videoAssetList; + unsigned int size = 0; + string dirPath = "gtest/002/video"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + videoAssetList = mediaLibClientInstance->GetVideoAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(videoAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetVideoAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get video assets from ROOT_DIR=/data/media directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetVideoAssets_test_002, TestSize.Level1) +{ + vector> videoAssetList; + unsigned int size = 0; + string dirPath = ""; + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + videoAssetList = mediaLibClientInstance->GetVideoAssets(dirPath, selectionArgs); + } + EXPECT_NE(videoAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media image asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_005, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_IMAGE; + + mediaAsset.name_ = "test_003_image.jpg"; + mediaAsset.albumName_ = "gtest/003/image"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media image asset in ROOT_DIR=/data/media directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_006, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_IMAGE; + + mediaAsset.name_ = "test_003_image.jpg"; + mediaAsset.albumName_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create existing media asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAsset_test_007, TestSize.Level1) +{ + bool errCode = true; + MediaAsset mediaAsset; + AssetType assetType = ASSET_IMAGE; + // create existing file + mediaAsset.name_ = "test_003_image.jpg"; + mediaAsset.albumName_ = "gtest/003/image"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAsset(assetType, mediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: GetImageAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get image assets present in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetImageAssets_test_001, TestSize.Level1) +{ + vector> imageAssetList; + unsigned int size = 0; + string dirPath = "gtest/003/image"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + imageAssetList = mediaLibClientInstance->GetImageAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(imageAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetImageAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get image assets from ROOT_DIR=/data/media directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetImageAssets_test_002, TestSize.Level1) +{ + vector> imageAssetList; + unsigned int size = 0; + string dirPath = ""; + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + imageAssetList = mediaLibClientInstance->GetImageAssets(dirPath, selectionArgs); + } + EXPECT_NE(imageAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetMediaAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get media assets present in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetMediaAssets_test_001, TestSize.Level1) +{ + vector> mediaAssetList; + unsigned int size = 0; + string dirPath = "gtest/003/image"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + mediaAssetList = mediaLibClientInstance->GetMediaAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(mediaAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetMediaAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get media assets from ROOT_DIR=/data/media directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetMediaAssets_test_002, TestSize.Level1) +{ + vector> mediaAssetList; + unsigned int size = 0; + string dirPath = ""; + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + mediaAssetList = mediaLibClientInstance->GetMediaAssets(dirPath, selectionArgs); + } + EXPECT_NE(mediaAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetImageAlbumAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get image media assets present in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetIMageAlbumAssets_test_001, TestSize.Level1) +{ + vector> albumAssetList; + unsigned int size = 0; + string dirPath = "gtest/003"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + albumAssetList = mediaLibClientInstance->GetImageAlbumAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(albumAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetImageAlbumAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get image album assets from ROOT_DIR=/data/media/ directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetImageAlbumAssets_test_002, TestSize.Level1) +{ + vector> albumAssetList; + unsigned int size = 0; + string dirPath = ""; + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + albumAssetList = mediaLibClientInstance->GetImageAlbumAssets(dirPath, selectionArgs); + } + EXPECT_NE(albumAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetVideoAlbumAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get video media assets present in particalar directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetVideoAlbumAssets_test_003, TestSize.Level1) +{ + vector> albumAssetList; + unsigned int size = 0; + string dirPath = "gtest/002"; + vector selectionArgs; + struct stat statInfo {}; + string dirPathCheck = "/data/media/" + dirPath; + + if (stat(dirPathCheck.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + albumAssetList = mediaLibClientInstance->GetVideoAlbumAssets(dirPath, selectionArgs); + } + } + } + EXPECT_NE(albumAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: GetVideoAlbumAssets + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Get video album assets from ROOT_DIR=/data/media directory and subdirectories. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_GetVideoAlbumAssets_test_004, TestSize.Level1) +{ + vector> albumAssetList; + unsigned int size = 0; + string dirPath = ""; + vector selectionArgs; + + if (mediaLibClientInstance != nullptr) { + albumAssetList = mediaLibClientInstance->GetVideoAlbumAssets(dirPath, selectionArgs); + } + EXPECT_NE(albumAssetList.size(), size); +} + +/* + * Feature: MediaLibrary + * Function: ModifyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Modify media audio asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_ModifyMediaAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + + srcMediaAsset.name_ = "test_001_audio.mp3"; + srcMediaAsset.uri_ = "/data/media/gtest/001/audio/test_001_audio.mp3"; + dstMediaAsset.name_ = "test_001_audio_modify.mp3"; + dstMediaAsset.uri_ = "/data/media/gtest/001/audio/test_001_audio.mp3"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->ModifyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: ModifyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Modify media audio mp3 file to wav in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_ModifyMediaAsset_test_002, TestSize.Level1) +{ + bool errCode = true; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + + srcMediaAsset.name_ = "test_002_audio.mp3"; + srcMediaAsset.uri_ = "/data/media/gtest/001/audio/test_002_audio.mp3"; + dstMediaAsset.name_ = "test_002_audio_modify.wav"; + dstMediaAsset.uri_ = "/data/media/gtest/001/audio/test_002_audio.mp3"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->ModifyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: ModifyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Modify media audio asset in requested non existing directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_ModifyMediaAsset_test_003, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + + srcMediaAsset.name_ = "test_002_audio.mp3"; + srcMediaAsset.uri_ = "/data/media/gtest/001/audio_nofile/test_002_audio.mp3"; + dstMediaAsset.uri_ = "/data/media/gtest/001/audio_nofile/test_002_audio.mp3"; + dstMediaAsset.name_ = "test_002_audio_modify.mp3"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->ModifyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CopyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: copy media asset to requested new directory, which gets created. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CopyMediaAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + // copy to requested ablumName + srcMediaAsset.name_ = "test_001_audio_modify.mp3"; + srcMediaAsset.uri_ = "/data/media/gtest/001/audio/test_001_audio_modify.mp3"; + dstMediaAsset.albumName_ = "gtest/001/copyaudio"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CopyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: copy media asset to requested non existing directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CopyMediaAsset_test_002, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_IMAGE; + // create and Copy to requested ablumName + srcMediaAsset.name_ = "test_003_image.jpg"; + srcMediaAsset.uri_ = "/data/media/gtest/003/image/test_003_image.jpg"; + dstMediaAsset.albumName_ = "copyjpg/001/image"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CopyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: copy media asset to ROOT_DIR=/data/media directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CopyMediaAsset_test_003, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + // copy to ROOT_DIR + srcMediaAsset.name_ = "test_001_audio_modify.mp3"; + srcMediaAsset.uri_ = "/data/media/gtest/001/copyaudio/test_001_audio_modify.mp3"; + dstMediaAsset.albumName_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CopyMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: copy media asset in requested directory without source file name . + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CopyMediaAsset_test_004, TestSize.Level1) +{ + bool errCode = false; + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType = ASSET_AUDIO; + + srcMediaAsset.name_ = ""; + srcMediaAsset.uri_ = "/data/media/gtest/001/audio/test_fail.mp3"; + dstMediaAsset.albumName_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Delete media audio asset from requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_AUDIO; + + mediaAsset.name_ = "test_001_audio_modify.mp3"; + mediaAsset.uri_ = "/data/media/gtest/001/copyaudio/test_001_audio_modify.mp3"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Delete media video asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAsset_test_002, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_VIDEO; + + mediaAsset.name_ = "test_002_video.mp4"; + mediaAsset.uri_ = "/data/media/gtest/002/video/test_002_video.mp4"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create media image asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAsset_test_003, TestSize.Level1) +{ + bool errCode = false; + MediaAsset mediaAsset; + AssetType assetType = ASSET_IMAGE; + + mediaAsset.name_ = "test_003_image.jpg"; + mediaAsset.uri_ = "/data/media/gtest/003/image/test_003_image.jpg"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAsset(assetType, mediaAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Delete media asset from requested empty directory path + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAsset_test_004, TestSize.Level1) +{ + bool errCode = true; + MediaAsset mediaAsset; + AssetType assetType = ASSET_AUDIO; + + mediaAsset.name_ = ""; + mediaAsset.uri_ = ""; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAsset(assetType, mediaAsset); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: CreateMediaAlbumAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Create album asset in requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_CreateMediaAlbumAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + AlbumAsset albumAsset; + AssetType assetType = ASSET_GENERIC_ALBUM; + + albumAsset.albumName_ = "gtest/crtalbum001"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->CreateMediaAlbumAsset(assetType, albumAsset); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: ModifyMediaAlbumAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Modify image album asset from requested directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_ModifyMediaAlbumAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + AlbumAsset srcAlbumAsset; + AlbumAsset dstAlbumAsset; + string albumUri; + AssetType assetType = ASSET_IMAGEALBUM; + + srcAlbumAsset.albumName_ = "copyjpg/001/image"; + dstAlbumAsset.albumName_ = "modify_image001"; + albumUri = "/data/media/copyjpg/001/image"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->ModifyMediaAlbumAsset(assetType, srcAlbumAsset, dstAlbumAsset, albumUri); + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: ModifyMediaAlbumAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Modify image album asset in requested "non existing" directory. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_ModifyMediaAlbumAsset_test_002, TestSize.Level1) +{ + bool errCode = true; + AlbumAsset srcAlbumAsset; + AlbumAsset dstAlbumAsset; + string albumUri; + AssetType assetType = ASSET_IMAGEALBUM; + + srcAlbumAsset.albumName_ = "test/album001"; + dstAlbumAsset.albumName_ = "modify_album002"; + albumUri = "/data/media/test2/album001"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->ModifyMediaAlbumAsset(assetType, srcAlbumAsset, dstAlbumAsset, albumUri); + } + EXPECT_EQ(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAlbumAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Delete media album from requested directory path. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAlbumAsset_test_001, TestSize.Level1) +{ + bool errCode = false; + AlbumAsset albumAsset; + string albumUri; + struct stat statInfo {}; + AssetType assetType = ASSET_IMAGEALBUM; + + albumAsset.albumName_ = "copyjpg/001/modify_image001"; + albumUri = "/data/media/copyjpg/001/modify_image001"; + if (stat(albumUri.c_str(), &statInfo) == 0) { + if (statInfo.st_mode & S_IFDIR) { + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAlbumAsset(assetType, albumAsset, albumUri); + } + } + } + EXPECT_NE(errCode, false); +} + +/* + * Feature: MediaLibrary + * Function: DeleteMediaAlbumAsset + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Delete media album from requested non existing path. + */ +HWTEST_F(MediaLibraryModuleTest, medialibrary_DeleteMediaAlbumAsset_test_002, TestSize.Level1) +{ + bool errCode = true; + AlbumAsset albumAsset; + string albumUri; + AssetType assetType = ASSET_IMAGEALBUM; + + albumAsset.albumName_ = "gtest/modify_album001"; + albumUri = "/data/media/test/modify_album002"; + if (mediaLibClientInstance != nullptr) { + errCode = mediaLibClientInstance->DeleteMediaAlbumAsset(assetType, albumAsset, albumUri); + } + EXPECT_EQ(errCode, false); +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/medialibrary_proxy/BUILD.gn b/frameworks/innerkitsimpl/medialibrary_proxy/BUILD.gn new file mode 100644 index 0000000000..ef06297278 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_proxy/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +MEDIA_LIB_BASE_DIR = "//foundation/multimedia/medialibrary_standard" +MEDIA_LIB_INNERKITS_DIR = "$MEDIA_LIB_BASE_DIR/frameworks/innerkitsimpl" + +config("medialib_proxy_public_config") { + include_dirs = [ + "$MEDIA_LIB_INNERKITS_DIR/medialibrary_proxy/include", + "$MEDIA_LIB_BASE_DIR/interfaces/innerkits/native/include", + "$MEDIA_LIB_INNERKITS_DIR/media_library/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + ] + + if (target_cpu == "arm") { + cflags = [ "-DBINDER_IPC_32BIT" ] + } +} + +ohos_shared_library("medialibrary_proxy") { + install_enable = true + sources = [ + "src/media_lib_proxy.cpp", + ] + + public_configs = [ ":medialib_proxy_public_config" ] + + deps = [ + "$MEDIA_LIB_INNERKITS_DIR/media_library:media_library", + "$MEDIA_LIB_INNERKITS_DIR/medialibrary_service:medialibrary_service", + "//utils/native/base:utils", + ] + + external_deps = [ + "ipc:ipc_core", + "hiviewdfx_hilog_native:libhilog", + "samgr_L2:samgr_proxy", + ] + subsystem_name = "multimedia" + part_name = "multimedia_media_library_standard" +} diff --git a/frameworks/innerkitsimpl/medialibrary_proxy/include/media_lib_proxy.h b/frameworks/innerkitsimpl/medialibrary_proxy/include/media_lib_proxy.h new file mode 100644 index 0000000000..bf85ed3789 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_proxy/include/media_lib_proxy.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIB_PROXY_H +#define MEDIA_LIB_PROXY_H + +#include "iremote_proxy.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" + +#include "IMediaLibraryClient.h" +#include "media_lib_service_const.h" +#include "media_lib_service_stub.h" + +namespace OHOS { +namespace Media { +class MediaLibProxy : public IRemoteProxy, public IMediaLibraryClient { +public: + explicit MediaLibProxy(const sptr &impl); + + virtual ~MediaLibProxy() = default; + + static IMediaLibraryClient *GetMediaLibraryClientInstance(); + + std::vector> GetMediaAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetAudioAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetVideoAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetImageAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetImageAlbumAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetVideoAlbumAssets(std::string selection, + std::vector selectionArgs) override; + + bool CreateMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) override; + + bool DeleteMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) override; + + bool ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) override; + + bool CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) override; + + bool CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset) override; + + bool DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset, + const std::string &albumUri) override; + + bool ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset &srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const std::string &albumUri) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_LIB_PROXY_H diff --git a/frameworks/innerkitsimpl/medialibrary_proxy/src/media_lib_proxy.cpp b/frameworks/innerkitsimpl/medialibrary_proxy/src/media_lib_proxy.cpp new file mode 100644 index 0000000000..5163f8a776 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_proxy/src/media_lib_proxy.cpp @@ -0,0 +1,584 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_lib_proxy.h" +#include "media_file_utils.h" +#include "media_log.h" + +using namespace std; +namespace OHOS { +namespace Media { +MediaLibProxy::MediaLibProxy(const sptr &impl) + : IRemoteProxy(impl) { } + +IMediaLibraryClient *IMediaLibraryClient::GetMediaLibraryClientInstance() +{ + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + MEDIA_ERR_LOG("samgr object is NULL."); + return nullptr; + } + sptr object = samgr->GetSystemAbility(MEDIA_LIBRARY_SERVICE_ID); + if (object == nullptr) { + MEDIA_ERR_LOG("Media Service object is NULL."); + } + static MediaLibProxy msProxy(object); + + return &msProxy; +} + +bool CopyUriToDstMediaAsset(const MediaAsset &assetData) +{ + bool errCode = false; + MediaAsset *dstAsset = (MediaAsset *)&assetData; + + // If albumname is empty, napi returns false + if (!(dstAsset->albumName_.empty())) { + dstAsset->uri_ = ROOT_MEDIA_DIR + SLASH_CHAR + dstAsset->albumName_; + errCode = true; + } + + return errCode; +} + +void ModifyDstMediaAssetUri(const MediaAsset &assetData) +{ + MediaAsset *dstAsset = (MediaAsset *)&assetData; + + size_t slashIndex = dstAsset->uri_.rfind("/"); + if (slashIndex != string::npos) { + string dirPath = dstAsset->uri_.substr(0, slashIndex); + dstAsset->uri_ = dirPath + "/" + dstAsset->name_; + } +} + +int32_t WriteCommonData(const MediaAsset &assetData, const MessageParcel &dataMsg) +{ + MessageParcel *data = (MessageParcel *)&dataMsg; + MediaAsset *asset = (MediaAsset *)&assetData; + + if (data->WriteInt32(asset->id_) && + data->WriteUint64(asset->size_) && + data->WriteInt32(asset->albumId_) && + data->WriteString(asset->albumName_) && + data->WriteString(asset->uri_) && + data->WriteInt32(asset->mediaType_) && + data->WriteString(asset->name_) && + data->WriteUint64(asset->dateAdded_) && + data->WriteUint64(asset->dateModified_)) { + return SUCCESS; + } + + return COMMON_DATA_WRITE_FAIL; +} + +void ReadCommonData(const MediaAsset &assetData, const MessageParcel &replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + MediaAsset *asset = (MediaAsset *)&assetData; + + asset->id_ = reply->ReadInt32(); + asset->size_ = reply->ReadUint64(); + asset->albumId_ = reply->ReadInt32(); + asset->albumName_ = reply->ReadString(); + asset->uri_ = reply->ReadString(); + asset->mediaType_ = (MediaType)reply->ReadInt32(); + asset->name_ = reply->ReadString(); + asset->dateAdded_ = reply->ReadUint64(); + asset->dateModified_ = reply->ReadUint64(); +} + +int32_t WriteAlbumdata(const AlbumAsset& assetData, const MessageParcel& dataMsg) +{ + MessageParcel *data = (MessageParcel *)&dataMsg; + AlbumAsset *albumAsset = (AlbumAsset *)&assetData; + + if (data->WriteInt32(albumAsset->albumId_) && + data->WriteString(albumAsset->albumName_)) { + return SUCCESS; + } + + return ALBUM_ASSET_WRITE_FAIL; +} + +void ReadMediaAlbumdata(const AlbumAsset& assetData, const MessageParcel& replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + AlbumAsset *albumAsset = (AlbumAsset *)&assetData; + + albumAsset->albumId_ = reply->ReadInt32(); + albumAsset->albumName_ = reply->ReadString(); +} + +int32_t ReadMediaList(vector> &mediaAssetList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr mediaAsset = make_unique(); + if (mediaAsset) { + ReadCommonData(*mediaAsset, reply); + mediaAssetList.push_back(move(mediaAsset)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::MediaAsset allocation failed"); + errCode = MEDIA_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +int32_t ReadImageList(vector> &imageAssetList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr imageAsset = make_unique(); + if (imageAsset) { + ReadCommonData(*imageAsset, reply); + imageAsset->width_ = reply.ReadInt32(); + imageAsset->height_ = reply.ReadInt32(); + imageAsset->mimeType_ = reply.ReadString(); + + imageAssetList.push_back(move(imageAsset)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::ImageAsset allocation failed"); + errCode = IMAGE_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +int32_t ReadVideoList(vector> &videoAssetList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr videoAsset = make_unique(); + if (videoAsset) { + ReadCommonData(*videoAsset, reply); + videoAsset->width_ = reply.ReadInt32(); + videoAsset->height_ = reply.ReadInt32(); + videoAsset->duration_ = reply.ReadInt32(); + videoAsset->mimeType_ = reply.ReadString(); + + videoAssetList.push_back(move(videoAsset)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::VideoAsset allocation failed"); + errCode = VIDEO_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +int32_t ReadAudioList(vector> &audioAssetList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr audioAsset = make_unique(); + if (audioAsset) { + ReadCommonData(*audioAsset, reply); + + audioAsset->title_ = reply.ReadString(); + audioAsset->artist_ = reply.ReadString(); + audioAsset->duration_ = reply.ReadInt32(); + audioAsset->mimeType_ = reply.ReadString(); + + audioAssetList.push_back(move(audioAsset)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::AudioAsset allocation failed"); + errCode = AUDIO_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +int32_t ReadImageAlbumList(vector> &imageAlbumList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr imageAlbum = make_unique(); + if (imageAlbum) { + imageAlbum->albumId_ = reply.ReadInt32(); + imageAlbum->albumName_ = reply.ReadString(); + + if (ReadImageList(imageAlbum->imageAssetList_, reply) == IMAGE_ASSET_READ_FAIL) { + MEDIA_ERR_LOG("MediaLibProxy::AlbumAsset read image list failed"); + errCode = IMAGEALBUM_ASSET_READ_FAIL; + break; + } + imageAlbumList.push_back(move(imageAlbum)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::AlbumAsset allocation failed"); + errCode = IMAGEALBUM_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +int32_t ReadVideoAlbumList(vector> &videoAlbumList, MessageParcel &reply) +{ + int32_t errCode = SUCCESS; + int32_t count = reply.ReadInt32(); + + for (int i = 0; i < count; i++) { + unique_ptr videoAlbum = make_unique(); + if (videoAlbum) { + videoAlbum->albumId_ = reply.ReadInt32(); + videoAlbum->albumName_ = reply.ReadString(); + + if (ReadVideoList(videoAlbum->videoAssetList_, reply) == VIDEO_ASSET_READ_FAIL) { + MEDIA_ERR_LOG("MediaLibProxy::AlbumAsset read video list failed"); + errCode = VIDEOALBUM_ASSET_READ_FAIL; + break; + } + videoAlbumList.push_back(move(videoAlbum)); + } else { + MEDIA_ERR_LOG("MediaLibProxy::AlbumAsset allocation failed"); + errCode = VIDEOALBUM_ASSET_READ_FAIL; + break; + } + } + + return errCode; +} + +vector> MediaLibProxy::GetImageAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> imageAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_IMAGE_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetImageAssets failed, error: %{public}d", error); + return imageAssetList; + } + (void)ReadImageList(imageAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return imageAssetList; +} + +vector> MediaLibProxy::GetAudioAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> audioAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_AUDIO_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetAudioAssets failed, error: %{public}d", error); + return audioAssetList; + } + (void)ReadAudioList(audioAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return audioAssetList; +} + +vector> MediaLibProxy::GetVideoAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> videoAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_VIDEO_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetVideoAssets failed, error: %{public}d", error); + return videoAssetList; + } + (void)ReadVideoList(videoAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return videoAssetList; +} + +vector> MediaLibProxy::GetMediaAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> mediaAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_MEDIA_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetMediaAssets failed, error: %{public}d", error); + return mediaAssetList; + } + (void)ReadMediaList(mediaAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return mediaAssetList; +} + +vector> MediaLibProxy::GetImageAlbumAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> albumAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_IMAGEALBUM_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetImageAlbumAssets failed, error: %{public}d", error); + return albumAssetList; + } + (void)ReadImageAlbumList(albumAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return albumAssetList; +} + +vector> MediaLibProxy::GetVideoAlbumAssets(string selection, + vector selArgs) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + vector> albumAssetList; + + if ((data.WriteString(selection)) && (data.WriteStringVector(selArgs))) { + int error = Remote()->SendRequest(MEDIA_GET_VIDEOALBUM_ASSETS, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("GetVideoAlbumAssets failed, error: %{public}d", error); + return albumAssetList; + } + (void)ReadVideoAlbumList(albumAssetList, reply); + } else { + MEDIA_ERR_LOG("data.WriteStringFailed"); + } + + return albumAssetList; +} + +bool MediaLibProxy::CreateMediaAsset(AssetType assetType, const MediaAsset& mediaAsset) +{ + bool errRet = true; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if ((data.WriteInt32(assetType) && (WriteCommonData(mediaAsset, data) == SUCCESS))) { + int error = Remote()->SendRequest(MEDIA_CREATE_MEDIA_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("CreateMedia failed, error: %{public}d", error); + errRet = false; + } + } else { + errRet = false; + MEDIA_ERR_LOG("CreateMediaAsset wrtie data failed !!"); + } + + return errRet; +} + +bool MediaLibProxy::DeleteMediaAsset(AssetType assetType, const MediaAsset& mediaAsset) +{ + bool errRet = true; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if ((data.WriteInt32(assetType) && (WriteCommonData(mediaAsset, data) == SUCCESS))) { + int error = Remote()->SendRequest(MEDIA_DELETE_MEDIA_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("DeleteMediaAsset SendRequest failed, error: %{public}d", error); + errRet = false; + } + } else { + errRet = false; + } + + return errRet; +} + +bool MediaLibProxy::ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) +{ + bool errRet = true; + MessageParcel data; + MessageParcel reply; + MessageOption option; + ModifyDstMediaAssetUri(dstMediaAsset); + if ((data.WriteInt32(assetType)) && (WriteCommonData(srcMediaAsset, data) == SUCCESS) && + (WriteCommonData(dstMediaAsset, data) == SUCCESS)) { + int error = Remote()->SendRequest(MEDIA_MODIFY_MEDIA_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("ModifyMediaAsset SendRequest failed, error: %{public}d", error); + errRet = false; + } + } else { + errRet = false; + MEDIA_ERR_LOG("ModifyMediaAsset write data failed !!"); + } + + return errRet; +} + +bool MediaLibProxy::CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) +{ + bool errRet = true; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if ((CopyUriToDstMediaAsset(dstMediaAsset) == true) && (data.WriteInt32(assetType)) && + (WriteCommonData(srcMediaAsset, data) == SUCCESS) && + (WriteCommonData(dstMediaAsset, data) == SUCCESS)) { + int error = Remote()->SendRequest(MEDIA_COPY_MEDIA_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("CopyMediaAsset SendRequest failed, error: %{public}d", error); + errRet = false; + } + } else { + errRet = false; + MEDIA_ERR_LOG("CopyMediaAsset: write data failed !!"); + } + + return errRet; +} + +bool MediaLibProxy::CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset& albumAsset) +{ + bool errRet = true; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if ((data.WriteInt32(assetType)) && (WriteAlbumdata(albumAsset, data) == SUCCESS)) { + int error = Remote()->SendRequest(MEDIA_CREATE_MEDIA_ALBUM_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("CreateMediaAlbumAsset SendRequest failed, error: %{public}d", error); + errRet = false; + } + } else { + MEDIA_ERR_LOG("CreateMediaAlbumAsset WriteAlbumdata failed"); + errRet = false; + } + + return errRet; +} + +bool MediaLibProxy::DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset& albumAsset, + const string &albumUri) +{ + bool errRet = false; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if ((assetType == ASSET_IMAGEALBUM) && (data.WriteInt32(assetType)) && + (WriteAlbumdata(albumAsset, data) == SUCCESS) && data.WriteString(albumUri)) { + MEDIA_ERR_LOG("DeleteMediaAlbumAsset-WriteAlbumdata done"); + errRet = true; + } else if ((assetType == ASSET_VIDEOALBUM) && (data.WriteInt32(assetType)) && + (WriteAlbumdata(albumAsset, data) == SUCCESS) && data.WriteString(albumUri)) { + MEDIA_ERR_LOG("DeleteMediaAlbumAsset-WriteAlbumdata done"); + errRet = true; + } + if (errRet == true) { + int error = Remote()->SendRequest(MEDIA_DELETE_MEDIA_ALBUM_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("DeleteMediaAlbumAsset SendRequest failed, error: %{public}d", error); + errRet = false; + } + } else { + MEDIA_ERR_LOG("DeleteMediaAlbumAsset-WriteAlbumdata Failed"); + } + + return errRet; +} + +bool MediaLibProxy::ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset& srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const string &albumUri) +{ + bool errRet = false; + MessageParcel data; + MessageParcel reply; + MessageOption option; + AlbumAsset *dstAsset = (AlbumAsset *)&dstAlbumAsset; + + if (data.WriteInt32(assetType)) { + if ((assetType == ASSET_IMAGEALBUM) && + (WriteAlbumdata(srcAlbumAsset, data) == SUCCESS) && + (WriteAlbumdata(dstAlbumAsset, data) == SUCCESS) && + data.WriteString(albumUri)) { + errRet = true; + } else if ((assetType == ASSET_VIDEOALBUM) && + (WriteAlbumdata(srcAlbumAsset, data) == SUCCESS) && + (WriteAlbumdata(dstAlbumAsset, data) == SUCCESS) && + data.WriteString(albumUri)) { + errRet = true; + } + + if (errRet == true) { + int error = Remote()->SendRequest(MEDIA_MODIFY_MEDIA_ALBUM_ASSET, data, reply, option); + if (error != ERR_NONE) { + MEDIA_ERR_LOG("ModifyMediaAlbumAsset SendRequest failed, error: %{public}d", error); + return false; + } + dstAsset->albumName_ = ROOT_MEDIA_DIR + "/" + dstAsset->albumName_; + } else { + MEDIA_ERR_LOG("ModifyMediaAlbumAsset: WriteAlbumdata failed"); + } + } else { + MEDIA_ERR_LOG("ModifyMediaAlbumAsset assetype write failed"); + } + + return errRet; +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/medialibrary_service/BUILD.gn b/frameworks/innerkitsimpl/medialibrary_service/BUILD.gn new file mode 100644 index 0000000000..dfbbbf5034 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_service/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +MEDIA_LIB_BASE_DIR = "//foundation/multimedia/medialibrary_standard" +MEDIA_LIB_INNERKITS_DIR = "$MEDIA_LIB_BASE_DIR/frameworks/innerkitsimpl" + +ohos_shared_library("medialibrary_service") { + install_enable = true + sources = [ + "src/media_lib_service.cpp", + "src/media_lib_service_stub.cpp", + ] + + cflags = [ "-fPIC" ] + cflags += [ "-Wall" ] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + cflags_cc = cflags + include_dirs = + [ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include/hilog" ] + + public_configs = [ ":medialibrary_external_library_config" ] + + deps = [ + "$MEDIA_LIB_INNERKITS_DIR/media_library:media_library", + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//utils/native/base:utils", + ] + + external_deps = [ + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + part_name = "multimedia_media_library_standard" + subsystem_name = "multimedia" +} + +config("medialibrary_external_library_config") { + include_dirs = [ "$MEDIA_LIB_INNERKITS_DIR/medialibrary_service/include" ] + include_dirs += [ "$MEDIA_LIB_BASE_DIR/interfaces/innerkits/native/include" ] +} diff --git a/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service.h b/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service.h new file mode 100644 index 0000000000..ff78f1fbdb --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIB_SERVICE_H +#define MEDIA_LIB_SERVICE_H + +#include "iremote_stub.h" +#include "system_ability.h" +#include "media_lib_service_stub.h" + +namespace OHOS { +namespace Media { +class MediaLibService : public SystemAbility, public MediaLibServiceStub { + DECLARE_SYSTEM_ABILITY(MediaLibService); +public: + DISALLOW_COPY_AND_MOVE(MediaLibService); + + explicit MediaLibService(int32_t systemAbilityId, bool runOnCreate = true); + virtual ~MediaLibService() = default; + + void OnDump() override; + + void OnStart() override; + + void OnStop() override; + + std::vector> GetMediaAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetImageAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetAudioAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetVideoAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetImageAlbumAssets(std::string selection, + std::vector selectionArgs) override; + + std::vector> GetVideoAlbumAssets(std::string selection, + std::vector selectionArgs) override; + + bool CreateMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) override; + + bool DeleteMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) override; + + bool ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) override; + + bool CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) override; + + bool CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset) override; + + bool DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset, + const std::string &albumUri) override; + + bool ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset &srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const std::string &albumUri) override; + +private: + std::unique_ptr mediaLibInstance = nullptr; +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_LIB_SERVICE_H diff --git a/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service_stub.h b/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service_stub.h new file mode 100644 index 0000000000..4b0eac786c --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_service/include/media_lib_service_stub.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIB_SERVICE_STUB_H +#define MEDIA_LIB_SERVICE_STUB_H + +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" +#include "media_library.h" + +namespace OHOS { +namespace Media { +class IMediaLibService : public IRemoteBroker { +public: + virtual std::vector> GetMediaAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual std::vector> GetImageAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual std::vector> GetAudioAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual std::vector> GetVideoAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual std::vector> GetImageAlbumAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual std::vector> GetVideoAlbumAssets(std::string selection, + std::vector selectionArgs) = 0; + + virtual bool CreateMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) = 0; + + virtual bool DeleteMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) = 0; + + virtual bool ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) = 0; + + virtual bool CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) = 0; + + virtual bool CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset) = 0; + + virtual bool DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset, + const std::string &albumUri) = 0; + + virtual bool ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset &srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const std::string &albumUri) = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"IMediaLibService"); +}; + +class MediaLibServiceStub : public IRemoteStub { +public: + virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) override; + + int ProcessMediaOperationRequests(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option); + + int32_t GetVideoAlbumAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t GetImageAlbumAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t GetVideoAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t GetAudioAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t GetMediaAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t GetImageAssetsOnRequest(MessageParcel &data, MessageParcel &reply); + + bool CreateMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool DeleteMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool ModifyMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool CopyMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool CreateAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool DeleteAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + bool ModifyAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply); + + int32_t WriteCommonData(const MediaAsset &asset, const MessageParcel &reply); + + int32_t WriteImageList(std::vector> &imageAssetList, + MessageParcel &reply); + + int32_t WriteAudioList(std::vector> &audioAssetList, + MessageParcel &reply); + + int32_t WriteVideoList(std::vector> &videoAssetList, + MessageParcel &reply); + + int32_t WriteMediaList(std::vector> &mediaAssetList, + MessageParcel &reply); + + int32_t WriteImageAlbum(std::vector> &albumAssetList, + MessageParcel &reply); + + int32_t WriteVideoAlbum(std::vector> &albumAssetList, + MessageParcel &reply); +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_LIB_SERVICE_STUB_H diff --git a/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service.cpp b/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service.cpp new file mode 100644 index 0000000000..4eceeed0c0 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_lib_service.h" +#include "iservice_registry.h" +#include "media_library.h" +#include "media_log.h" +#include "system_ability_definition.h" + +using namespace std; + +namespace OHOS { +namespace Media { +REGISTER_SYSTEM_ABILITY_BY_ID(MediaLibService, MEDIA_LIBRARY_SERVICE_ID, true); + +MediaLibService::MediaLibService(int32_t systemAbilityId, bool runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate) { } + +void MediaLibService::OnDump() { } + +void MediaLibService::OnStart() +{ + MEDIA_INFO_LOG(" MediaLibService::OnStart() called"); + bool res = Publish(this); + if (res) { + MEDIA_DEBUG_LOG("MediaLibService OnStart res valid"); + } + mediaLibInstance = MediaLibrary::GetMediaLibraryInstance(); + if (mediaLibInstance == nullptr) { + MEDIA_ERR_LOG("GetMediaLibraryInstance failed"); + } +} + +void MediaLibService::OnStop() +{ + MEDIA_INFO_LOG("MediaLibService::OnStop() called"); + mediaLibInstance = nullptr; +} + +vector> MediaLibService::GetMediaAssets(string selection, vector selArgs) +{ + vector> mediaAssetList; + + if (mediaLibInstance != nullptr) { + mediaAssetList = mediaLibInstance->GetMediaAssets(selection, selArgs); + } + return mediaAssetList; +} + +vector> MediaLibService::GetImageAssets(string selection, vector selArgs) +{ + vector> imageAssetList; + + if (mediaLibInstance != nullptr) { + imageAssetList = mediaLibInstance->GetImageAssets(selection, selArgs); + } + return imageAssetList; +} + +vector> MediaLibService::GetAudioAssets(string selection, vector selArgs) +{ + vector> audioAssetList; + + if (mediaLibInstance != nullptr) { + audioAssetList = mediaLibInstance->GetAudioAssets(selection, selArgs); + } + return audioAssetList; +} + +vector> MediaLibService::GetVideoAssets(string selection, vector selArgs) +{ + vector> videoAssetList; + + if (mediaLibInstance != nullptr) { + videoAssetList = mediaLibInstance->GetVideoAssets(selection, selArgs); + } + return videoAssetList; +} + +vector> MediaLibService::GetImageAlbumAssets(string selection, vector selArgs) +{ + vector> albumAsset; + int32_t requestType = MediaType::MEDIA_TYPE_IMAGE; + + if (mediaLibInstance != nullptr) { + albumAsset = mediaLibInstance->GetAlbumAssets(selection, selArgs, requestType); + } + return albumAsset; +} + +vector> MediaLibService::GetVideoAlbumAssets(string selection, vector selArgs) +{ + vector> albumAsset; + int32_t requestType = MediaType::MEDIA_TYPE_VIDEO; + + if (mediaLibInstance != nullptr) { + albumAsset = mediaLibInstance->GetAlbumAssets(selection, selArgs, requestType); + } + return albumAsset; +} + +bool MediaLibService::CreateMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) +{ + bool errCode = false; + MediaAsset *asset = (MediaAsset *)&mediaAsset; + + if (mediaLibInstance != nullptr && (asset != nullptr)) { + errCode = mediaLibInstance->CreateMediaAsset(assetType, mediaAsset); + } + + return errCode; +} + +bool MediaLibService::DeleteMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) +{ + bool errCode = false; + MediaAsset *asset = (MediaAsset *)&mediaAsset; + + if (mediaLibInstance != nullptr && (asset != nullptr)) { + errCode = mediaLibInstance->DeleteMediaAsset(assetType, mediaAsset); + } + + return errCode; +} + +bool MediaLibService::ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) +{ + bool errCode = false; + MediaAsset *srcAsset = (MediaAsset *)&srcMediaAsset; + MediaAsset *dstAsset = (MediaAsset *)&dstMediaAsset; + + if (mediaLibInstance != nullptr && (srcAsset != nullptr) && (dstAsset != nullptr)) { + errCode = mediaLibInstance->ModifyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + + return errCode; +} + +bool MediaLibService::CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) +{ + bool errCode = false; + MediaAsset *srcAsset = (MediaAsset *)&srcMediaAsset; + MediaAsset *dstAsset = (MediaAsset *)&dstMediaAsset; + + if (mediaLibInstance != nullptr && (srcAsset != nullptr) && (dstAsset != nullptr)) { + errCode = mediaLibInstance->CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); + } + + return errCode; +} + +bool MediaLibService::CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset) +{ + bool errCode = false; + AlbumAsset *asset = (AlbumAsset *)&albumAsset; + + if (mediaLibInstance != nullptr && (asset != nullptr)) { + errCode = mediaLibInstance->CreateMediaAlbumAsset(assetType, albumAsset); + } + + return errCode; +} + +bool MediaLibService::DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset, + const string &albumUri) +{ + bool errCode = false; + AlbumAsset *asset = (AlbumAsset *)&albumAsset; + + if (mediaLibInstance != nullptr && (asset != nullptr) && (!albumUri.empty())) { + errCode = mediaLibInstance->DeleteMediaAlbumAsset(assetType, albumAsset, albumUri); + } + + return errCode; +} + +bool MediaLibService::ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset &srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const string &albumUri) +{ + bool errCode = false; + AlbumAsset *srcAsset = (AlbumAsset *)&srcAlbumAsset; + AlbumAsset *dstAsset = (AlbumAsset *)&dstAlbumAsset; + + if (mediaLibInstance != nullptr && (srcAsset != nullptr) && (dstAsset != nullptr) && + (!albumUri.empty())) { + errCode = mediaLibInstance->ModifyMediaAlbumAsset(assetType, srcAlbumAsset, dstAlbumAsset, albumUri); + } + + return errCode; +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service_stub.cpp b/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service_stub.cpp new file mode 100644 index 0000000000..b788e8b752 --- /dev/null +++ b/frameworks/innerkitsimpl/medialibrary_service/src/media_lib_service_stub.cpp @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_lib_service_stub.h" + +#include "media_lib_service.h" +#include "media_lib_service_const.h" +#include "media_log.h" + + +using namespace std; + +namespace OHOS { +namespace Media { +int32_t MediaLibServiceStub::WriteCommonData(const MediaAsset &assetData, const MessageParcel &replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + MediaAsset *asset = (MediaAsset *)&assetData; + + if (reply->WriteInt32(asset->id_) && + reply->WriteUint64(asset->size_) && + reply->WriteInt32(asset->albumId_) && + reply->WriteString(asset->albumName_) && + reply->WriteString(asset->uri_) && + reply->WriteInt32(asset->mediaType_) && + reply->WriteString(asset->name_) && + reply->WriteUint64(asset->dateAdded_) && + reply->WriteUint64(asset->dateModified_)) { + return SUCCESS; + } + return COMMON_DATA_WRITE_FAIL; +} + +void ReadCommonData(const MediaAsset &assetData, const MessageParcel &replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + MediaAsset *asset = (MediaAsset *)&assetData; + + asset->id_ = reply->ReadInt32(); + asset->size_ = reply->ReadUint64(); + asset->albumId_ = reply->ReadInt32(); + asset->albumName_ = reply->ReadString(); + asset->uri_ = reply->ReadString(); + asset->mediaType_ = (MediaType)reply->ReadInt32(); + asset->name_ = reply->ReadString(); + asset->dateAdded_ = reply->ReadUint64(); + asset->dateModified_ = reply->ReadUint64(); +} + +int32_t WriteImageAlbumdata(const AlbumAsset& albumAssetData, const MessageParcel& replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + AlbumAsset *albumAsset = (AlbumAsset *)&albumAssetData; + + if (reply->WriteInt32(albumAsset->albumId_) && + reply->WriteString(albumAsset->albumName_)) { + return SUCCESS; + } + + return IMAGEALBUM_ASSET_WRITE_FAIL; +} + +int32_t WriteVideoAlbumdata(const AlbumAsset& albumAssetData, const MessageParcel& replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + AlbumAsset *albumAsset = (AlbumAsset *)&albumAssetData; + + if (reply->WriteInt32(albumAsset->albumId_) && + reply->WriteString(albumAsset->albumName_)) { + return SUCCESS; + } + + return VIDEOALBUM_ASSET_WRITE_FAIL; +} + +void ReadMediaAlbumdata(const AlbumAsset& albumAssetData, const MessageParcel& replyMsg) +{ + MessageParcel *reply = (MessageParcel *)&replyMsg; + AlbumAsset *albumAsset = (AlbumAsset *)&albumAssetData; + + albumAsset->albumId_ = reply->ReadInt32(); + albumAsset->albumName_ = reply->ReadString(); +} + +int32_t MediaLibServiceStub::WriteImageList(vector> &imageAssetList, + MessageParcel &reply) +{ + int32_t errCode = IMAGE_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)imageAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + ImageAsset *imageAsset = imageAssetList[i].get(); + if (imageAsset != nullptr) { + if (WriteCommonData(*imageAsset, reply) == SUCCESS) { + if (reply.WriteInt32(imageAsset->width_) && + reply.WriteInt32(imageAsset->height_) && + reply.WriteString(imageAsset->mimeType_)) { + errCode = SUCCESS; + } + } + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::WriteAudioList(vector> &audioAssetList, + MessageParcel &reply) +{ + int32_t errCode = AUDIO_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)audioAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + AudioAsset *audioAsset = audioAssetList[i].get(); + if (audioAsset != nullptr) { + if (WriteCommonData(*audioAsset, reply) == SUCCESS) { + if (reply.WriteString(audioAsset->title_) && + reply.WriteString(audioAsset->artist_) && + reply.WriteInt32(audioAsset->duration_) && + reply.WriteString(audioAsset->mimeType_)) { + errCode = SUCCESS; + } + } + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::WriteVideoList(vector> &videoAssetList, + MessageParcel &reply) +{ + int32_t errCode = VIDEO_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)videoAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + VideoAsset *videoAsset = videoAssetList[i].get(); + if (videoAsset != nullptr) { + if (WriteCommonData(*videoAsset, reply) == SUCCESS) { + if (reply.WriteInt32(videoAsset->width_) && + reply.WriteInt32(videoAsset->height_) && + reply.WriteInt32(videoAsset->duration_) && + reply.WriteString(videoAsset->mimeType_)) { + errCode = SUCCESS; + } + } + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::WriteMediaList(vector> &mediaAssetList, + MessageParcel &reply) +{ + int32_t errCode = MEDIA_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)mediaAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + MediaAsset *mediaAsset = mediaAssetList[i].get(); + if (mediaAsset != nullptr) { + errCode = WriteCommonData(*mediaAsset, reply); + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::WriteImageAlbum(vector> &albumAssetList, + MessageParcel &reply) +{ + int32_t errCode = IMAGEALBUM_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)albumAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + AlbumAsset *albumAsset = albumAssetList[i].get(); + if (reply.WriteInt32(albumAsset->albumId_) && + reply.WriteString(albumAsset->albumName_)) { + errCode = WriteImageList(albumAsset->imageAssetList_, reply); + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::WriteVideoAlbum(vector> &albumAssetList, + MessageParcel &reply) +{ + int32_t errCode = VIDEOALBUM_ASSET_WRITE_FAIL; + int32_t size; + + size = (int32_t)albumAssetList.size(); + if (reply.WriteInt32(size)) { + for (int32_t i = 0; i < size; i++) { + AlbumAsset *albumAsset = albumAssetList[i].get(); + if (reply.WriteInt32(albumAsset->albumId_) && + reply.WriteString(albumAsset->albumName_)) { + errCode = WriteVideoList(albumAsset->videoAssetList_, reply); + } + } + } + return errCode; +} + +int32_t MediaLibServiceStub::GetVideoAlbumAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string albumDirPath; + vector selArgs; + + albumDirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> albumAssetList = GetVideoAlbumAssets(albumDirPath, selArgs); + + return WriteVideoAlbum(albumAssetList, reply); +} + +int32_t MediaLibServiceStub::GetImageAlbumAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string albumDirPath; + vector selArgs; + + albumDirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> albumAssetList = GetImageAlbumAssets(albumDirPath, selArgs); + + return WriteImageAlbum(albumAssetList, reply); +} + +int32_t MediaLibServiceStub::GetVideoAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string dirPath; + vector selArgs; + + dirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> videoAssetList = GetVideoAssets(dirPath, selArgs); + + return WriteVideoList(videoAssetList, reply); +} + +int32_t MediaLibServiceStub::GetAudioAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string dirPath; + vector selArgs; + + dirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> audioAssetList = GetAudioAssets(dirPath, selArgs); + + return WriteAudioList(audioAssetList, reply); +} + +int32_t MediaLibServiceStub::GetMediaAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string dirPath; + vector selArgs; + + dirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> mediaAssetList = GetMediaAssets(dirPath, selArgs); + + return WriteMediaList(mediaAssetList, reply); +} + +int32_t MediaLibServiceStub::GetImageAssetsOnRequest(MessageParcel &data, + MessageParcel &reply) +{ + string dirPath; + vector selArgs; + + dirPath = data.ReadString(); + data.ReadStringVector(&selArgs); + vector> imageAssetList = GetImageAssets(dirPath, selArgs); + + return WriteImageList(imageAssetList, reply); +} + +bool MediaLibServiceStub::CreateMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + MediaAsset mediaAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadCommonData(mediaAsset, data); + + return CreateMediaAsset(assetType, mediaAsset); +} + +bool MediaLibServiceStub::DeleteMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + MediaAsset mediaAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadCommonData(mediaAsset, data); + + return DeleteMediaAsset(assetType, mediaAsset); +} + +bool MediaLibServiceStub::ModifyMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadCommonData(srcMediaAsset, data); + ReadCommonData(dstMediaAsset, data); + + return ModifyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); +} + +bool MediaLibServiceStub::CopyMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + MediaAsset srcMediaAsset; + MediaAsset dstMediaAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadCommonData(srcMediaAsset, data); + ReadCommonData(dstMediaAsset, data); + + return CopyMediaAsset(assetType, srcMediaAsset, dstMediaAsset); +} + +bool MediaLibServiceStub::CreateAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + AlbumAsset albumAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadMediaAlbumdata(albumAsset, data); + + return CreateMediaAlbumAsset(assetType, albumAsset); +} + +bool MediaLibServiceStub::DeleteAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + AlbumAsset albumAsset; + AssetType assetType; + string albumUri; + + assetType = (AssetType)data.ReadInt32(); + ReadMediaAlbumdata(albumAsset, data); + albumUri = data.ReadString(); + + return DeleteMediaAlbumAsset(assetType, albumAsset, albumUri); +} + +bool MediaLibServiceStub::ModifyAlbumMediaOnRequest(MessageParcel &data, MessageParcel &reply) +{ + AlbumAsset srcAlbumAsset; + AlbumAsset dstAlbumAsset; + AssetType assetType; + + assetType = (AssetType)data.ReadInt32(); + ReadMediaAlbumdata(srcAlbumAsset, data); + ReadMediaAlbumdata(dstAlbumAsset, data); + + string albumPath = data.ReadString(); + + return ModifyMediaAlbumAsset(assetType, srcAlbumAsset, dstAlbumAsset, albumPath); +} + +int MediaLibServiceStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + int32_t errCode = SUCCESS; + + MEDIA_INFO_LOG(" MediaLibServiceStub::OnRemoteRequest called.code: %{public}d", code); + if (code > MEDIA_GET_VIDEOALBUM_ASSETS) { + errCode = ProcessMediaOperationRequests(code, data, reply, option); + } else { + switch (code) { + case MEDIA_GET_IMAGE_ASSETS: + errCode = GetImageAssetsOnRequest(data, reply); + break; + case MEDIA_GET_MEDIA_ASSETS: + errCode = GetMediaAssetsOnRequest(data, reply); + break; + case MEDIA_GET_AUDIO_ASSETS: + errCode = GetAudioAssetsOnRequest(data, reply); + break; + case MEDIA_GET_VIDEO_ASSETS: + errCode = GetVideoAssetsOnRequest(data, reply); + break; + case MEDIA_GET_IMAGEALBUM_ASSETS: + errCode = GetImageAlbumAssetsOnRequest(data, reply); + break; + case MEDIA_GET_VIDEOALBUM_ASSETS: + errCode = GetVideoAlbumAssetsOnRequest(data, reply); + break; + default: + MEDIA_INFO_LOG("Default called"); + break; + } + } + + MEDIA_INFO_LOG(" MediaLibServiceStub: errCode: %{public}d", errCode); + return errCode; +} + +int MediaLibServiceStub::ProcessMediaOperationRequests(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + int32_t errCode = SUCCESS; + + switch (code) { + case MEDIA_CREATE_MEDIA_ASSET: { + if ((CreateMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_DELETE_MEDIA_ASSET: { + if ((DeleteMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_MODIFY_MEDIA_ASSET: { + if ((ModifyMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_COPY_MEDIA_ASSET: { + if ((CopyMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_CREATE_MEDIA_ALBUM_ASSET: { + if ((CreateAlbumMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_DELETE_MEDIA_ALBUM_ASSET: { + if ((DeleteAlbumMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + case MEDIA_MODIFY_MEDIA_ALBUM_ASSET: { + if ((ModifyAlbumMediaOnRequest(data, reply) != true)) + errCode = FAIL; + break; + } + default: + MEDIA_INFO_LOG("ProcessMediaOperationRequests :Default called"); + break; + } + + return errCode; +} +} // namespace Media +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/prebuilts/etcs/BUILD.gn b/frameworks/innerkitsimpl/prebuilts/etcs/BUILD.gn new file mode 100644 index 0000000000..2fc1a28004 --- /dev/null +++ b/frameworks/innerkitsimpl/prebuilts/etcs/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("medialibrary_service.rc") { + if (use_musl) { + source = "medialibrary_service.cfg" + } else { + source = "medialibrary_service.rc" + } + relative_install_dir = "init" + part_name = "multimedia_media_library_standard" + subsystem_name = "multimedia" +} diff --git a/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.cfg b/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.cfg new file mode 100644 index 0000000000..8219679b6a --- /dev/null +++ b/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.cfg @@ -0,0 +1,14 @@ +{ + "jobs" : [{ + "name" : "boot", + "cmds" : [ + "start medialibrary_service" + ] + } + ], + "services" : [{ + "name" : "medialibrary_service", + "path" : ["/system/bin/sa_main", "/system/profile/medialibrary_service.xml"] + } + ] +} diff --git a/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.rc b/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.rc new file mode 100644 index 0000000000..c600068261 --- /dev/null +++ b/frameworks/innerkitsimpl/prebuilts/etcs/medialibrary_service.rc @@ -0,0 +1,20 @@ +# 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. + +service medialibrary_service /system/bin/sa_main /system/profile/medialibrary_service.xml + class z_core + seclabel u:r:audiodistributedservice:s0 + +on boot + start medialibrary_service + diff --git a/frameworks/kitsimpl/medialibrary/src/album_asset_napi.cpp b/frameworks/kitsimpl/medialibrary/src/album_asset_napi.cpp new file mode 100644 index 0000000000..1d60cb4924 --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/album_asset_napi.cpp @@ -0,0 +1,622 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "album_asset_napi.h" +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AlbumAssetNapi"}; + const int32_t DEFAULT_ALBUM_ID = 0; + const std::string DEFAULT_ALBUM_NAME = "Unknown"; +} + +namespace OHOS { +napi_ref AlbumAssetNapi::sConstructor_ = nullptr; +Media::AlbumAsset *AlbumAssetNapi::sAlbumAsset_ = nullptr; +AlbumType AlbumAssetNapi::sAlbumType_ = TYPE_NONE; +Media::IMediaLibraryClient *AlbumAssetNapi::sMediaLibrary_ = nullptr; + +Media::AssetType GetAlbumType(AlbumType type) +{ + Media::AssetType result; + + switch (type) { + case TYPE_VIDEO_ALBUM: + result = Media::ASSET_VIDEOALBUM; + break; + case TYPE_IMAGE_ALBUM: + result = Media::ASSET_IMAGEALBUM; + break; + case TYPE_NONE: + default: + result = Media::ASSET_GENERIC_ALBUM; + } + + return result; +} + +AlbumAssetNapi::AlbumAssetNapi() + : mediaLibrary_(nullptr), env_(nullptr), wrapper_(nullptr) +{ + albumId_ = DEFAULT_ALBUM_ID; + albumName_ = DEFAULT_ALBUM_NAME; + type_ = TYPE_NONE; +} + +AlbumAssetNapi::~AlbumAssetNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void AlbumAssetNapi::AlbumAssetNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + AlbumAssetNapi *album = reinterpret_cast(nativeObject); + if (album != nullptr) { + album->~AlbumAssetNapi(); + } +} + +napi_value AlbumAssetNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor album_asset_props[] = { + DECLARE_NAPI_GETTER("albumId", GetAlbumId), + DECLARE_NAPI_GETTER_SETTER("albumName", GetAlbumName, JSSetAlbumName), + DECLARE_NAPI_FUNCTION("getVideoAssets", GetVideoAssets), + DECLARE_NAPI_FUNCTION("getImageAssets", GetImageAssets), + DECLARE_NAPI_FUNCTION("commitCreate", CommitCreate), + DECLARE_NAPI_FUNCTION("commitDelete", CommitDelete), + DECLARE_NAPI_FUNCTION("commitModify", CommitModify) + }; + + status = napi_define_class(env, ALBUM_ASSET_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + AlbumAssetNapiConstructor, nullptr, + sizeof(album_asset_props) / sizeof(album_asset_props[PARAM0]), + album_asset_props, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, ALBUM_ASSET_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value AlbumAssetNapi::AlbumAssetNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->type_ = sAlbumType_; + obj->mediaLibrary_ = sMediaLibrary_; + if (sAlbumAsset_ != nullptr) { + obj->UpdateAlbumAssetInfo(); + + for (size_t i = 0; i < sAlbumAsset_->videoAssetList_.size(); i++) { + obj->videoAssets_.push_back(std::move(sAlbumAsset_->videoAssetList_[i])); + do { + std::string videoPath = obj->videoAssets_[i]->uri_; + size_t slashIndex = videoPath.rfind("/"); + if (slashIndex != std::string::npos) { + obj->albumPath_ = videoPath.substr(0, slashIndex); + } + } while (false); + } + for (size_t i = 0; i < sAlbumAsset_->imageAssetList_.size(); i++) { + obj->imageAssets_.push_back(std::move(sAlbumAsset_->imageAssetList_[i])); + do { + std::string imagePath = obj->imageAssets_[i]->uri_; + size_t slashIndex = imagePath.rfind("/"); + if (slashIndex != std::string::npos) { + obj->albumPath_ = imagePath.substr(0, slashIndex); + } + } while (false); + } + } else { + HiLog::Error(LABEL, "No native instance assigned yet"); + return result; + } + + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + AlbumAssetNapi::AlbumAssetNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failure wrapping js to native napi"); + } + } + } + + return result; +} + +napi_value AlbumAssetNapi::CreateAlbumAsset(napi_env env, AlbumType type, + Media::AlbumAsset &aAsset, Media::IMediaLibraryClient &mediaLibClient) +{ + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sAlbumAsset_ = &aAsset; + sAlbumType_ = type; + sMediaLibrary_ = &mediaLibClient; + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sAlbumAsset_ = nullptr; + if (status == napi_ok && result != nullptr) { + return result; + } else { + HiLog::Error(LABEL, "Failed to create album asset instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value AlbumAssetNapi::GetAlbumId(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AlbumAssetNapi* obj = nullptr; + int32_t id; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + id = obj->albumId_; + status = napi_create_int32(env, id, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value AlbumAssetNapi::JSSetAlbumName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value undefinedResult = nullptr; + AlbumAssetNapi* obj = nullptr; + napi_valuetype valueType = napi_undefined; + size_t res; + char buffer[SIZE]; + + napi_get_undefined(env, &undefinedResult); + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter"); + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) { + HiLog::Error(LABEL, "Invalid arguments type!"); + return undefinedResult; + } + + status = napi_get_value_string_utf8(env, argv[PARAM0], buffer, SIZE, &res); + if (status == napi_ok) { + obj->newAlbumName_ = buffer; + } + } + + return undefinedResult; +} + +napi_value AlbumAssetNapi::GetAlbumName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AlbumAssetNapi* obj = nullptr; + std::string name = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + name = obj->albumName_; + status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +Media::IMediaLibraryClient* AlbumAssetNapi::GetMediaLibClientInstance() +{ + Media::IMediaLibraryClient *ins = this->mediaLibrary_; + return ins; +} + +static void VideoAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value videoArray = nullptr; + napi_value vAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->videoAssets.empty()) { + size_t len = context->videoAssets.size(); + if (napi_create_array(env, &videoArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + vAsset = VideoAssetNapi::CreateVideoAsset(env, *(context->videoAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (vAsset == nullptr || napi_set_element(env, videoArray, i, vAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get video asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = videoArray; + } + } + } else { + HiLog::Error(LABEL, "No video assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value AlbumAssetNapi::GetVideoAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetVideoAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + AlbumAsyncContext* context = static_cast(data); + for (size_t i = 0; i < context->objectInfo->videoAssets_.size(); i += 1) { + context->videoAssets.push_back(std::move(context->objectInfo->videoAssets_[i])); + } + }, + VideoAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +static void ImageAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value imageArray = nullptr; + napi_value iAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->imageAssets.empty()) { + size_t len = context->imageAssets.size(); + if (napi_create_array(env, &imageArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + iAsset = ImageAssetNapi::CreateImageAsset(env, *(context->imageAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (iAsset == nullptr || napi_set_element(env, imageArray, i, iAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get image asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = imageArray; + } + } + } else { + HiLog::Error(LABEL, "No image assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value AlbumAssetNapi::GetImageAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetImageAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + AlbumAsyncContext* context = static_cast(data); + for (size_t i = 0; i < context->objectInfo->imageAssets_.size(); i += 1) { + context->imageAssets.push_back(std::move(context->objectInfo->imageAssets_[i])); + } + }, + ImageAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +void AlbumAssetNapi::UpdateAlbumAssetInfo() +{ + albumId_ = sAlbumAsset_->albumId_; + albumName_ = sAlbumAsset_->albumName_; +} + +static void CommonCompleteCallback(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + napi_get_boolean(env, context->status, &result[PARAM1]); + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value AlbumAssetNapi::CommitCreate(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitCreate"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::AlbumAsset asset; + if (!context->objectInfo->newAlbumName_.empty()) { + asset.albumId_ = context->objectInfo->albumId_; + asset.albumName_ = context->objectInfo->newAlbumName_; + context->status = context->objectInfo->mediaLibrary_->CreateMediaAlbumAsset( + GetAlbumType(context->objectInfo->type_), asset); + if (context->status) { + context->objectInfo->albumName_ = context->objectInfo->newAlbumName_; + } + } else { + context->status = false; + } + context->objectInfo->newAlbumName_ = ""; + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value AlbumAssetNapi::CommitDelete(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitDelete"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::AlbumAsset asset; + std::string albumUri = context->objectInfo->albumPath_; + + asset.albumId_ = context->objectInfo->albumId_; + asset.albumName_ = context->objectInfo->albumName_; + + context->status = context->objectInfo->mediaLibrary_->DeleteMediaAlbumAsset( + GetAlbumType(context->objectInfo->type_), asset, albumUri); + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value AlbumAssetNapi::CommitModify(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitModify"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::AlbumAsset assetOld, assetNew; + std::string albumUri = context->objectInfo->albumPath_; + + assetOld.albumId_ = context->objectInfo->albumId_; + assetOld.albumName_ = context->objectInfo->albumName_; + + assetNew.albumId_ = context->objectInfo->albumId_; + if (!context->objectInfo->newAlbumName_.empty()) { + if (context->objectInfo->newAlbumName_.compare(context->objectInfo->albumName_) != 0) { + assetNew.albumName_ = context->objectInfo->newAlbumName_; + context->status = context->objectInfo->mediaLibrary_->ModifyMediaAlbumAsset( + GetAlbumType(context->objectInfo->type_), assetOld, assetNew, albumUri); + if (context->status) { + context->objectInfo->albumName_ = assetNew.albumName_; + } + } else { + HiLog::Error(LABEL, "New name cannot be same as the old one"); + context->status = false; + } + context->objectInfo->newAlbumName_ = ""; + } else { + HiLog::Error(LABEL, "No modification values provided"); + context->status = false; + } + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/audio_asset_napi.cpp b/frameworks/kitsimpl/medialibrary/src/audio_asset_napi.cpp new file mode 100644 index 0000000000..8f0d314ab9 --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/audio_asset_napi.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_asset_napi.h" +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AudioAssetNapi"}; + const int32_t DEFAULT_AUDIO_DURATION = 0; + const std::string DEFAULT_AUDIO_TITLE = "Unknown"; + const std::string DEFAULT_AUDIO_ARTIST = "Unknown"; + const std::string DEFAULT_AUDIO_MIME_TYPE = "audio/*"; +} + +namespace OHOS { +napi_ref AudioAssetNapi::sConstructor_ = nullptr; +Media::AudioAsset *AudioAssetNapi::sAudioAsset_ = nullptr; +Media::IMediaLibraryClient *AudioAssetNapi::sMediaLibrary_ = nullptr; + +AudioAssetNapi::AudioAssetNapi() + : env_(nullptr), wrapper_(nullptr) +{ + duration_ = DEFAULT_AUDIO_DURATION; + title_ = DEFAULT_AUDIO_TITLE; + artist_ = DEFAULT_AUDIO_ARTIST; + mimeType_ = DEFAULT_AUDIO_MIME_TYPE; +} + +AudioAssetNapi::~AudioAssetNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void AudioAssetNapi::AudioAssetNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + AudioAssetNapi *audio = reinterpret_cast(nativeObject); + if (audio != nullptr) { + audio->~AudioAssetNapi(); + } +} + +napi_value AudioAssetNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor audio_asset_props[] = { + DECLARE_NAPI_GETTER("mimeType", GetMimeType), + DECLARE_NAPI_GETTER("title", GetTitle), + DECLARE_NAPI_GETTER("artist", GetArtist), + DECLARE_NAPI_GETTER("duration", GetDuration), + DECLARE_NAPI_GETTER("id", GetId), + DECLARE_NAPI_GETTER("URI", GetUri), + DECLARE_NAPI_GETTER("mediaType", GetMediaType), + DECLARE_NAPI_GETTER("size", GetSize), + DECLARE_NAPI_GETTER("dateAdded", GetDateAdded), + DECLARE_NAPI_GETTER("dateModified", GetDateModified), + DECLARE_NAPI_GETTER("albumId", GetAlbumId), + DECLARE_NAPI_GETTER_SETTER("albumName", GetAlbumName, JSSetAlbumName), + DECLARE_NAPI_GETTER_SETTER("name", GetName, JSSetName), + DECLARE_NAPI_FUNCTION("startCreate", StartCreate), + DECLARE_NAPI_FUNCTION("cancelCreate", CancelCreate), + DECLARE_NAPI_FUNCTION("commitCreate", CommitCreate), + DECLARE_NAPI_FUNCTION("startModify", StartModify), + DECLARE_NAPI_FUNCTION("cancelModify", CancelModify), + DECLARE_NAPI_FUNCTION("commitModify", CommitModify), + DECLARE_NAPI_FUNCTION("commitDelete", CommitDelete), + DECLARE_NAPI_FUNCTION("commitCopy", CommitCopy), + }; + + status = napi_define_class(env, AUDIO_ASSET_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + AudioAssetNapiConstructor, nullptr, + sizeof(audio_asset_props) / sizeof(audio_asset_props[PARAM0]), + audio_asset_props, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, AUDIO_ASSET_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value AudioAssetNapi::AudioAssetNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->SetMediaLibraryClient(*sMediaLibrary_); + if (sAudioAsset_ != nullptr) { + obj->UpdateAudioAssetInfo(); + } else { + HiLog::Error(LABEL, "No native instance assigned yet"); + return result; + } + + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + AudioAssetNapi::AudioAssetNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failure wrapping js to native napi"); + } + } + } + + return result; +} + +napi_value AudioAssetNapi::CreateAudioAsset(napi_env env, Media::AudioAsset &aAsset, + Media::IMediaLibraryClient &mediaLibClient) +{ + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sAudioAsset_ = &aAsset; + sMediaLibrary_ = &mediaLibClient; + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sAudioAsset_ = nullptr; + if (status == napi_ok && result != nullptr) { + return result; + } else { + HiLog::Error(LABEL, "Failed to create audio asset instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value AudioAssetNapi::GetMimeType(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AudioAssetNapi* obj = nullptr; + std::string mimeType = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + mimeType = obj->mimeType_; + status = napi_create_string_utf8(env, mimeType.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value AudioAssetNapi::GetTitle(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AudioAssetNapi* obj = nullptr; + std::string title = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + title = obj->title_; + status = napi_create_string_utf8(env, title.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value AudioAssetNapi::GetArtist(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AudioAssetNapi* obj = nullptr; + std::string artist = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + artist = obj->artist_; + status = napi_create_string_utf8(env, artist.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value AudioAssetNapi::GetDuration(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + AudioAssetNapi* obj = nullptr; + int32_t duration; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + duration = obj->duration_; + status = napi_create_int32(env, duration, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +void AudioAssetNapi::UpdateAudioAssetInfo() +{ + this->SetId(sAudioAsset_->id_); + this->SetUri(sAudioAsset_->uri_); + this->SetMediaType(static_cast(sAudioAsset_->mediaType_)); + this->SetName(sAudioAsset_->name_); + this->SetSize(sAudioAsset_->size_); + this->SetDateAdded(sAudioAsset_->dateAdded_); + this->SetDateModified(sAudioAsset_->dateModified_); + this->SetAlbumName(sAudioAsset_->albumName_); + this->SetAlbumId(sAudioAsset_->albumId_); + mimeType_ = sAudioAsset_->mimeType_; + title_ = sAudioAsset_->title_; + artist_ = sAudioAsset_->artist_; + duration_ = sAudioAsset_->duration_; +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/image_asset_napi.cpp b/frameworks/kitsimpl/medialibrary/src/image_asset_napi.cpp new file mode 100644 index 0000000000..aa14e3d5d1 --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/image_asset_napi.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "image_asset_napi.h" +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ImageAssetNapi"}; + const int32_t DEFAULT_IMAGE_WIDTH = 1280; + const int32_t DEFAULT_IMAGE_HEIGHT = 720; + const std::string DEFAULT_IMAGE_MIME_TYPE = "image/*"; +} + +namespace OHOS { +napi_ref ImageAssetNapi::sConstructor_ = nullptr; +Media::ImageAsset *ImageAssetNapi::sImageAsset_ = nullptr; +Media::IMediaLibraryClient *ImageAssetNapi::sMediaLibrary_ = nullptr; + +ImageAssetNapi::ImageAssetNapi() + : env_(nullptr), wrapper_(nullptr) +{ + width_ = DEFAULT_IMAGE_WIDTH; + height_ = DEFAULT_IMAGE_HEIGHT; + mimeType_ = DEFAULT_IMAGE_MIME_TYPE; +} + +ImageAssetNapi::~ImageAssetNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void ImageAssetNapi::ImageAssetNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + ImageAssetNapi *image = reinterpret_cast(nativeObject); + if (image != nullptr) { + image->~ImageAssetNapi(); + } +} + +napi_value ImageAssetNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor image_asset_props[] = { + DECLARE_NAPI_GETTER("mimeType", GetMimeType), + DECLARE_NAPI_GETTER("width", GetWidth), + DECLARE_NAPI_GETTER("height", GetHeight), + DECLARE_NAPI_GETTER("id", GetId), + DECLARE_NAPI_GETTER("URI", GetUri), + DECLARE_NAPI_GETTER("mediaType", GetMediaType), + DECLARE_NAPI_GETTER("size", GetSize), + DECLARE_NAPI_GETTER("dateAdded", GetDateAdded), + DECLARE_NAPI_GETTER("dateModified", GetDateModified), + DECLARE_NAPI_GETTER("albumId", GetAlbumId), + DECLARE_NAPI_GETTER_SETTER("albumName", GetAlbumName, JSSetAlbumName), + DECLARE_NAPI_GETTER_SETTER("name", GetName, JSSetName), + DECLARE_NAPI_FUNCTION("startCreate", StartCreate), + DECLARE_NAPI_FUNCTION("cancelCreate", CancelCreate), + DECLARE_NAPI_FUNCTION("commitCreate", CommitCreate), + DECLARE_NAPI_FUNCTION("startModify", StartModify), + DECLARE_NAPI_FUNCTION("cancelModify", CancelModify), + DECLARE_NAPI_FUNCTION("commitModify", CommitModify), + DECLARE_NAPI_FUNCTION("commitDelete", CommitDelete), + DECLARE_NAPI_FUNCTION("commitCopy", CommitCopy), + }; + + status = napi_define_class(env, IMAGE_ASSET_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + ImageAssetNapiConstructor, nullptr, + sizeof(image_asset_props) / sizeof(image_asset_props[PARAM0]), + image_asset_props, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, IMAGE_ASSET_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value ImageAssetNapi::ImageAssetNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->SetMediaLibraryClient(*sMediaLibrary_); + if (sImageAsset_ != nullptr) { + obj->UpdateImageAssetInfo(); + } else { + HiLog::Error(LABEL, "No native instance assigned yet"); + return result; + } + + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + ImageAssetNapi::ImageAssetNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failure wrapping js to native napi"); + } + } + } + + return result; +} + +napi_value ImageAssetNapi::CreateImageAsset(napi_env env, Media::ImageAsset &iAsset, + Media::IMediaLibraryClient &mediaLibClient) +{ + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sImageAsset_ = &iAsset; + sMediaLibrary_ = &mediaLibClient; + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sImageAsset_ = nullptr; + if (status == napi_ok && result != nullptr) { + return result; + } else { + HiLog::Error(LABEL, "Failed to create image asset instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value ImageAssetNapi::GetMimeType(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + ImageAssetNapi* obj = nullptr; + std::string mimeType = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + mimeType = obj->mimeType_; + status = napi_create_string_utf8(env, mimeType.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value ImageAssetNapi::GetWidth(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + ImageAssetNapi* obj = nullptr; + int32_t width; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + width = obj->width_; + status = napi_create_int32(env, width, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value ImageAssetNapi::GetHeight(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + ImageAssetNapi* obj = nullptr; + int32_t height; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + height = obj->height_; + status = napi_create_int32(env, height, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +void ImageAssetNapi::UpdateImageAssetInfo() +{ + this->SetId(sImageAsset_->id_); + this->SetUri(sImageAsset_->uri_); + this->SetMediaType(static_cast(sImageAsset_->mediaType_)); + this->SetName(sImageAsset_->name_); + this->SetSize(sImageAsset_->size_); + this->SetDateAdded(sImageAsset_->dateAdded_); + this->SetDateModified(sImageAsset_->dateModified_); + this->SetAlbumName(sImageAsset_->albumName_); + this->SetAlbumId(sImageAsset_->albumId_); + mimeType_ = sImageAsset_->mimeType_; + width_ = sImageAsset_->width_; + height_ = sImageAsset_->height_; +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/media_asset_napi.cpp b/frameworks/kitsimpl/medialibrary/src/media_asset_napi.cpp new file mode 100644 index 0000000000..678758bebc --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/media_asset_napi.cpp @@ -0,0 +1,1006 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_asset_napi.h" +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "MediaAssetNapi"}; + const int32_t DEFAULT_MEDIA_ID = 0; + const int32_t DEFAULT_ALBUM_ID = 0; + const uint64_t DEFAULT_MEDIA_SIZE = 0; + const uint64_t DEFAULT_MEDIA_DATE_ADDED = 0; + const uint64_t DEFAULT_MEDIA_DATE_MODIFIED = 0; + const std::string DEFAULT_MEDIA_URI = ""; + const OHOS::Media::MediaType DEFAULT_MEDIA_TYPE = OHOS::Media::MEDIA_TYPE_FILE; + const std::string DEFAULT_MEDIA_NAME = "Unknown"; + const std::string DEFAULT_ALBUM_NAME = "Unknown"; +} + +namespace OHOS { +napi_ref MediaAssetNapi::sConstructor_ = nullptr; +Media::MediaAsset *MediaAssetNapi::sMediaAsset_ = nullptr; +Media::IMediaLibraryClient *MediaAssetNapi::sMediaLibrary_ = nullptr; + +Media::AssetType GetAssetType(Media::MediaType type) +{ + Media::AssetType result; + + switch (type) { + case Media::MEDIA_TYPE_AUDIO: + result = Media::ASSET_AUDIO; + break; + case Media::MEDIA_TYPE_VIDEO: + result = Media::ASSET_VIDEO; + break; + case Media::MEDIA_TYPE_IMAGE: + result = Media::ASSET_IMAGE; + break; + case Media::MEDIA_TYPE_MEDIA: + result = Media::ASSET_MEDIA; + break; + default: + result = Media::ASSET_NONE; + break; + } + + return result; +} + +MediaAssetNapi::MediaAssetNapi() + : env_(nullptr), wrapper_(nullptr) +{ + mediaLibrary_ = nullptr; + id_ = DEFAULT_MEDIA_ID; + albumId_ = DEFAULT_ALBUM_ID; + albumName_ = DEFAULT_ALBUM_NAME; + size_ = DEFAULT_MEDIA_SIZE; + uri_ = DEFAULT_MEDIA_URI; + mediaType_ = static_cast(DEFAULT_MEDIA_TYPE); + name_ = DEFAULT_MEDIA_NAME; + dateAdded_ = DEFAULT_MEDIA_DATE_ADDED; + dateModified_ = DEFAULT_MEDIA_DATE_MODIFIED; +} + +MediaAssetNapi::~MediaAssetNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void MediaAssetNapi::MediaAssetNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + MediaAssetNapi *media = reinterpret_cast(nativeObject); + if (media != nullptr) { + media->~MediaAssetNapi(); + } +} + +napi_value MediaAssetNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor media_asset_properties[] = { + DECLARE_NAPI_GETTER("id", GetId), + DECLARE_NAPI_GETTER("URI", GetUri), + DECLARE_NAPI_GETTER("mediaType", GetMediaType), + DECLARE_NAPI_GETTER("size", GetSize), + DECLARE_NAPI_GETTER("dateAdded", GetDateAdded), + DECLARE_NAPI_GETTER("dateModified", GetDateModified), + DECLARE_NAPI_GETTER("albumId", GetAlbumId), + DECLARE_NAPI_GETTER_SETTER("albumName", GetAlbumName, JSSetAlbumName), + DECLARE_NAPI_GETTER_SETTER("name", GetName, JSSetName), + DECLARE_NAPI_FUNCTION("startCreate", StartCreate), + DECLARE_NAPI_FUNCTION("cancelCreate", CancelCreate), + DECLARE_NAPI_FUNCTION("commitCreate", CommitCreate), + DECLARE_NAPI_FUNCTION("startModify", StartModify), + DECLARE_NAPI_FUNCTION("cancelModify", CancelModify), + DECLARE_NAPI_FUNCTION("commitModify", CommitModify), + DECLARE_NAPI_FUNCTION("commitDelete", CommitDelete), + DECLARE_NAPI_FUNCTION("commitCopy", CommitCopy), + }; + + status = napi_define_class(env, MEDIA_ASSET_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + MediaAssetNapiConstructor, nullptr, + sizeof(media_asset_properties) / sizeof(media_asset_properties[PARAM0]), + media_asset_properties, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, MEDIA_ASSET_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value MediaAssetNapi::MediaAssetNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->mediaLibrary_ = sMediaLibrary_; + if (sMediaAsset_ != nullptr) { + obj->UpdateMediaAssetInfo(*sMediaAsset_); + } else { + HiLog::Error(LABEL, "No native instance assigned yet"); + return result; + } + + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + MediaAssetNapi::MediaAssetNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failure wrapping js to native napi"); + } + } + } + + return result; +} + +napi_value MediaAssetNapi::CreateMediaAsset(napi_env env, Media::MediaAsset &mAsset, + Media::IMediaLibraryClient &mediaLibClient) +{ + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sMediaAsset_ = &mAsset; + sMediaLibrary_ = &mediaLibClient; + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sMediaAsset_ = nullptr; + if (status == napi_ok && result != nullptr) { + return result; + } else { + HiLog::Error(LABEL, "Failed to create media asset instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +void MediaAssetNapi::SetId(int32_t id) +{ + this->id_ = id; +} + +void MediaAssetNapi::SetUri(std::string uri) +{ + this->uri_ = uri; +} + +void MediaAssetNapi::SetMediaType(int32_t mediaType) +{ + this->mediaType_ = mediaType; +} + +void MediaAssetNapi::SetName(std::string name) +{ + this->name_ = name; +} + +void MediaAssetNapi::SetSize(uint64_t size) +{ + this->size_ = size; +} + +void MediaAssetNapi::SetDateAdded(uint64_t dateAdded) +{ + this->dateAdded_ = dateAdded; +} + +void MediaAssetNapi::SetDateModified(uint64_t dateModified) +{ + this->dateModified_ = dateModified; +} + +void MediaAssetNapi::SetAlbumName(std::string albumName) +{ + this->albumName_ = albumName; +} + +void MediaAssetNapi::SetAlbumId(int32_t albumId) +{ + this->albumId_ = albumId; +} + +void MediaAssetNapi::SetMediaLibraryClient(Media::IMediaLibraryClient &mediaLibrary) +{ + this->mediaLibrary_ = &mediaLibrary; +} + +napi_value MediaAssetNapi::GetId(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + int32_t id; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + id = obj->id_; + status = napi_create_uint32(env, id, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetUri(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + std::string uri = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + uri = obj->uri_; + status = napi_create_string_utf8(env, uri.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetMediaType(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + int32_t mediaType; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + mediaType = obj->mediaType_; + status = napi_create_int32(env, mediaType, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::JSSetName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + napi_valuetype valueType = napi_undefined; + size_t res; + char buffer[SIZE]; + + napi_get_undefined(env, &undefinedResult); + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter"); + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + if (obj->startCreateFlag == false && obj->startModifyFlag == false) { + HiLog::Error(LABEL, "No Permission to set the values"); + return undefinedResult; + } + + if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) { + HiLog::Error(LABEL, "Invalid arguments type!"); + return undefinedResult; + } + + status = napi_get_value_string_utf8(env, argv[PARAM0], buffer, SIZE, &res); + if (status == napi_ok) { + obj->newName_ = buffer; + return undefinedResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + std::string name = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + name = obj->name_; + status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetSize(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + uint64_t size; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + size = obj->size_; + status = napi_create_int64(env, size, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetDateAdded(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + uint64_t dateAdded; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + dateAdded = obj->dateAdded_; + status = napi_create_int64(env, dateAdded, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetDateModified(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + uint64_t dateModified; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + dateModified = obj->dateModified_; + status = napi_create_int64(env, dateModified, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetAlbumId(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + int32_t id; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + id = obj->albumId_; + status = napi_create_int32(env, id, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::JSSetAlbumName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + napi_valuetype valueType = napi_undefined; + size_t res; + char buffer[SIZE]; + + napi_get_undefined(env, &undefinedResult); + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter"); + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + if (obj->startCreateFlag == false) { + HiLog::Error(LABEL, "No Permission to set the values"); + return undefinedResult; + } + + if (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok || valueType != napi_string) { + HiLog::Error(LABEL, "Invalid arguments type!"); + return undefinedResult; + } + + status = napi_get_value_string_utf8(env, argv[PARAM0], buffer, SIZE, &res); + if (status == napi_ok) { + obj->newAlbumName_ = buffer; + return undefinedResult; + } + } + + return undefinedResult; +} + +napi_value MediaAssetNapi::GetAlbumName(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + MediaAssetNapi* obj = nullptr; + std::string name = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + name = obj->albumName_; + status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +void MediaAssetNapi::UpdateMediaAssetInfo(OHOS::Media::MediaAsset &mAsset) +{ + OHOS::Media::MediaAsset *mediaAsset = &mAsset; + + id_ = mediaAsset->id_; + uri_ = mediaAsset->uri_; + mediaType_ = static_cast(mediaAsset->mediaType_); + name_ = mediaAsset->name_; + size_ = mediaAsset->size_; + dateAdded_ = mediaAsset->dateAdded_; + dateModified_ = mediaAsset->dateModified_; + albumId_ = mediaAsset->albumId_; + albumName_ = mediaAsset->albumName_; +} + +static void CommonCompleteCallback(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + napi_get_boolean(env, context->status, &result[PARAM1]); + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaAssetNapi::StartCreate(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "StartCreate"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + context->objectInfo->startCreateFlag = true; + context->status = true; + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +void MediaAssetNapi::UpdateNativeMediaAsset(Media::MediaAsset& mAsset) +{ + mAsset.id_ = id_; + mAsset.uri_ = uri_; + mAsset.mediaType_ = static_cast(mediaType_); + mAsset.name_ = name_; + mAsset.size_ = size_; + mAsset.dateAdded_ = dateAdded_; + mAsset.dateModified_ = dateModified_; + mAsset.albumId_ = albumId_; + mAsset.albumName_ = albumName_; +} + +napi_value MediaAssetNapi::CommitCreate(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitCreate"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::MediaAsset asset; + + context->objectInfo->UpdateNativeMediaAsset(asset); + if (!context->objectInfo->newAlbumName_.empty()) { + asset.albumName_ = context->objectInfo->newAlbumName_; + } else { + HiLog::Error(LABEL, "Album name is empty"); + asset.albumName_ = ""; + } + if (!context->objectInfo->newName_.empty()) { + asset.name_ = context->objectInfo->newName_; + context->status = + context->objectInfo->mediaLibrary_->CreateMediaAsset(GetAssetType(asset.mediaType_), asset); + if (context->status) { + context->objectInfo->UpdateMediaAssetInfo(asset); + } + } else { + context->status = false; + } + context->objectInfo->newName_ = ""; + context->objectInfo->newAlbumName_ = ""; + context->objectInfo->startCreateFlag = false; + }, CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaAssetNapi::CancelCreate(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CancelCreate"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + if (!context->objectInfo->newName_.empty()) { + context->objectInfo->newName_ = ""; + } + if (!context->objectInfo->newAlbumName_.empty()) { + context->objectInfo->newAlbumName_ = ""; + } + context->objectInfo->startCreateFlag = false; + context->status = true; + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaAssetNapi::StartModify(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "StartModify"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + context->objectInfo->startModifyFlag = true; + context->status = true; + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaAssetNapi::CommitModify(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitModify"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::MediaAsset assetOld, assetNew; + + context->status = false; + context->objectInfo->UpdateNativeMediaAsset(assetOld); + context->objectInfo->UpdateNativeMediaAsset(assetNew); + + if (!context->objectInfo->newName_.empty()) { + if (context->objectInfo->newName_.compare(context->objectInfo->name_) != 0) { + assetNew.name_ = context->objectInfo->newName_; + + context->status = + context->objectInfo->mediaLibrary_->ModifyMediaAsset(GetAssetType(assetOld.mediaType_), + assetOld, assetNew); + if (context->status) { + context->objectInfo->name_ = assetNew.name_; + context->objectInfo->uri_ = assetNew.uri_; + } + } else { + HiLog::Error(LABEL, "New name cannot be same as the old one"); + } + context->objectInfo->newName_ = ""; + } else { + HiLog::Error(LABEL, "No modification values provided"); + } + context->objectInfo->startModifyFlag = false; + }, CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaAssetNapi::CancelModify(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CancelModify"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + if (!context->objectInfo->newName_.empty()) { + context->objectInfo->newName_ = ""; + } + context->objectInfo->startModifyFlag = false; + context->status = true; + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaAssetNapi::CommitDelete(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + const int32_t refCount = 1; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= 1, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + if (argc == ARGS_ONE) { + GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef); + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitDelete"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::MediaAsset asset; + context->objectInfo->UpdateNativeMediaAsset(asset); + context->status = + context->objectInfo->mediaLibrary_->DeleteMediaAsset(GetAssetType(asset.mediaType_), asset); + }, + CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value GetCommitCopyParams(napi_env env, size_t argCount, const napi_value argv[], + MediaAssetAsyncContext &context) +{ + const int32_t refCount = 1; + napi_value result; + auto asyncContext = &context; + + NAPI_ASSERT(env, argv != nullptr, "Argument list is empty"); + + for (size_t i = PARAM0; i < argCount; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + if ((i == PARAM0) && (valueType == napi_object)) { + napi_unwrap(env, argv[i], reinterpret_cast(&asyncContext->targetCopyObject)); + } else if ((i == PARAM1) && (valueType == napi_function)) { + napi_create_reference(env, argv[i], refCount, &asyncContext->callbackRef); + } else { + NAPI_ASSERT(env, false, "type mismatch"); + } + } + + // Return true napi_value if params are successfully obtained + napi_get_boolean(env, true, &result); + return result; +} + +napi_value MediaAssetNapi::CommitCopy(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc >= ARGS_ONE, "requires 1 parameter minimum"); + + status = napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = GetCommitCopyParams(env, argc, argv, *asyncContext); + if (result == nullptr) { + napi_get_undefined(env, &result); + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CommitCopy"); + + status = napi_create_async_work( + env, nullptr, resource, [](napi_env env, void* data) { + auto context = static_cast(data); + Media::MediaAsset assetSrc, assetTarget; + + context->objectInfo->UpdateNativeMediaAsset(assetSrc); + context->targetCopyObject->UpdateNativeMediaAsset(assetTarget); + + if (!context->targetCopyObject->newAlbumName_.empty()) { + assetTarget.albumName_ = context->targetCopyObject->newAlbumName_; + + context->status = context->objectInfo->mediaLibrary_->CopyMediaAsset( + GetAssetType(assetSrc.mediaType_), assetSrc, assetTarget); + if (context->status) { + context->targetCopyObject->UpdateMediaAssetInfo(assetTarget); + } + } else { + context->status = false; + } + context->targetCopyObject->newAlbumName_ = ""; + context->targetCopyObject->startCreateFlag = false; + }, CommonCompleteCallback, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/media_library_napi.cpp b/frameworks/kitsimpl/medialibrary/src/media_library_napi.cpp new file mode 100644 index 0000000000..c82b8021de --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/media_library_napi.cpp @@ -0,0 +1,888 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "media_library_napi.h" +#include +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "MediaLibraryNapi"}; +} + +namespace OHOS { +napi_ref MediaLibraryNapi::sConstructor_ = nullptr; + +MediaLibraryNapi::MediaLibraryNapi() + : mediaLibrary_(nullptr), env_(nullptr), wrapper_(nullptr) {} + +MediaLibraryNapi::~MediaLibraryNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void MediaLibraryNapi::MediaLibraryNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + MediaLibraryNapi *mediaLibrary = reinterpret_cast(nativeObject); + if (mediaLibrary != nullptr) { + mediaLibrary->~MediaLibraryNapi(); + } +} + +napi_value MediaLibraryNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor media_library_properties[] = { + DECLARE_NAPI_FUNCTION("getMediaAssets", GetMediaAssets), + DECLARE_NAPI_FUNCTION("getAudioAssets", GetAudioAssets), + DECLARE_NAPI_FUNCTION("getVideoAssets", GetVideoAssets), + DECLARE_NAPI_FUNCTION("getImageAssets", GetImageAssets), + DECLARE_NAPI_FUNCTION("getVideoAlbums", GetVideoAlbums), + DECLARE_NAPI_FUNCTION("getImageAlbums", GetImageAlbums), + DECLARE_NAPI_FUNCTION("createVideoAsset", CreateVideoAsset), + DECLARE_NAPI_FUNCTION("createImageAsset", CreateImageAsset), + DECLARE_NAPI_FUNCTION("createAudioAsset", CreateAudioAsset), + DECLARE_NAPI_FUNCTION("createAlbum", CreateAlbum) + }; + + napi_property_descriptor static_prop[] = { + DECLARE_NAPI_STATIC_FUNCTION("getMediaLibraryHelper", GetMediaLibraryInstance), + }; + + status = napi_define_class(env, MEDIA_LIBRARY_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + MediaLibraryNapiConstructor, nullptr, + sizeof(media_library_properties) / sizeof(media_library_properties[PARAM0]), + media_library_properties, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, MEDIA_LIBRARY_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + status = napi_define_properties(env, exports, + sizeof(static_prop) / sizeof(static_prop[PARAM0]), static_prop); + if (status == napi_ok) { + return exports; + } + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value MediaLibraryNapi::MediaLibraryNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->mediaLibrary_ = Media::IMediaLibraryClient::GetMediaLibraryClientInstance(); + if (obj->mediaLibrary_ == nullptr) { + HiLog::Error(LABEL, "MediaLibrary client instance creation failed!"); + return result; + } + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + MediaLibraryNapi::MediaLibraryNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failed to wrap the native media lib client object with JS"); + } + } + } + + return result; +} + +napi_value MediaLibraryNapi::GetMediaLibraryInstance(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + napi_value ctor; + + status = napi_get_reference_value(env, sConstructor_, &ctor); + if (status == napi_ok) { + status = napi_new_instance(env, ctor, 0, nullptr, &result); + if (status == napi_ok) { + return result; + } else { + HiLog::Error(LABEL, "New instance could not be obtained"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +Media::IMediaLibraryClient* MediaLibraryNapi::GetMediaLibClientInstance() +{ + Media::IMediaLibraryClient *ins = this->mediaLibrary_; + return ins; +} + +void GetFetchOptionsParam(napi_env env, napi_value arg, const std::string& str, + const std::vector& strArr, bool &err) +{ + napi_value selection = nullptr; + char buffer[SIZE]; + size_t res; + std::string strItem; + uint32_t len = 0; + napi_value selectionArgs = nullptr; + napi_value stringItem = nullptr; + bool present = false; + auto selectionStr = const_cast(&str); + auto selectionStrArray = const_cast *>(&strArr); + + if (napi_get_named_property(env, arg, "selections", &selection) != napi_ok + || napi_get_value_string_utf8(env, selection, buffer, SIZE, &res) != napi_ok) { + HiLog::Error(LABEL, "Could not get the string argument!"); + err = true; + } else { + *selectionStr = buffer; + memset_s(buffer, SIZE, 0, sizeof(buffer)); + } + + napi_has_named_property(env, arg, "selectionArgs", &present); + if (present && napi_get_named_property(env, arg, "selectionArgs", &selectionArgs) == napi_ok) { + napi_get_array_length(env, selectionArgs, &len); + for (size_t i = 0; i < len; i++) { + napi_get_element(env, selectionArgs, i, &stringItem); + napi_get_value_string_utf8(env, stringItem, buffer, SIZE, &res); + strItem = buffer; + selectionStrArray->push_back(strItem); + memset_s(buffer, SIZE, 0, sizeof(buffer)); + } + } else { + HiLog::Error(LABEL, "Could not get the string argument!"); + err = true; + } +} + +napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[], + MediaLibraryAsyncContext &asyncContext) +{ + std::string str = ""; + std::vector strArr; + bool err = false; + const int32_t refCount = 1; + napi_value result; + auto context = &asyncContext; + + NAPI_ASSERT(env, argv != nullptr, "Argument list is empty"); + + for (size_t i = PARAM0; i < argc; i++) { + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[i], &valueType); + + if (i == PARAM0 && valueType == napi_object) { + GetFetchOptionsParam(env, argv[PARAM0], str, strArr, err); + if (!err) { + context->selection = str; + context->selectionArgs = strArr; + } else { + NAPI_ASSERT(env, false, "type mismatch"); + } + } else if (i == PARAM0 && valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &context->callbackRef); + break; + } else if (i == PARAM1 && valueType == napi_function) { + napi_create_reference(env, argv[i], refCount, &context->callbackRef); + break; + } else { + NAPI_ASSERT(env, false, "type mismatch"); + } + } + + // Return true napi_value if params are successfully obtained + napi_get_boolean(env, true, &result); + return result; +} + +static void MediaAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value mediaArray = nullptr; + napi_value mAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->mediaAssets.empty()) { + size_t len = context->mediaAssets.size(); + if (napi_create_array(env, &mediaArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + mAsset = MediaAssetNapi::CreateMediaAsset(env, *(context->mediaAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (mAsset == nullptr || napi_set_element(env, mediaArray, i, mAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get media asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = mediaArray; + } + } else { + napi_get_undefined(env, &result[PARAM1]); + } + } else { + HiLog::Error(LABEL, "No media assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaLibraryNapi::GetMediaAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetMediaAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->mediaAssets = context->objectInfo->mediaLibrary_->GetMediaAssets(context->selection, + context->selectionArgs); + context->status = 0; + }, + MediaAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +static void AudioAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value audioArray = nullptr; + napi_value aAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->audioAssets.empty()) { + size_t len = context->audioAssets.size(); + if (napi_create_array(env, &audioArray) == napi_ok) { + size_t i = 0; + for (; i < len; i++) { + aAsset = AudioAssetNapi::CreateAudioAsset(env, *(context->audioAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (aAsset == nullptr || napi_set_element(env, audioArray, i, aAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get audio asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = audioArray; + } + } else { + napi_get_undefined(env, &result[PARAM1]); + } + } else { + HiLog::Error(LABEL, "No audio assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaLibraryNapi::GetAudioAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetAudioAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->audioAssets = context->objectInfo->mediaLibrary_->GetAudioAssets(context->selection, + context->selectionArgs); + context->status = 0; + }, + AudioAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +static void VideoAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value videoArray = nullptr; + napi_value vAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->videoAssets.empty()) { + size_t len = context->videoAssets.size(); + if (napi_create_array(env, &videoArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + vAsset = VideoAssetNapi::CreateVideoAsset(env, *(context->videoAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (vAsset == nullptr || napi_set_element(env, videoArray, i, vAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get video asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = videoArray; + } + } else { + napi_get_undefined(env, &result[PARAM1]); + } + } else { + HiLog::Error(LABEL, "No video assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaLibraryNapi::GetVideoAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetVideoAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->videoAssets = context->objectInfo->mediaLibrary_->GetVideoAssets(context->selection, + context->selectionArgs); + context->status = 0; + }, + VideoAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +static void ImageAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value imageArray = nullptr; + napi_value iAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->imageAssets.empty()) { + size_t len = context->imageAssets.size(); + if (napi_create_array(env, &imageArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + iAsset = ImageAssetNapi::CreateImageAsset(env, *(context->imageAssets[i]), + *(context->objectInfo->GetMediaLibClientInstance())); + if (iAsset == nullptr || napi_set_element(env, imageArray, i, iAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get image asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = imageArray; + } + } else { + napi_get_undefined(env, &result[PARAM1]); + } + } else { + HiLog::Error(LABEL, "No image assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaLibraryNapi::GetImageAssets(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc <= ARGS_TWO, "requires 2 parameters maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetImageAssets"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->imageAssets = context->objectInfo->mediaLibrary_->GetImageAssets(context->selection, + context->selectionArgs); + context->status = 0; + }, + ImageAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +static void AlbumAssetsAsyncCallbackComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + napi_value albumArray = nullptr; + napi_value albumAsset = nullptr; + + if (context == nullptr) { + HiLog::Error(LABEL, "Async context is null"); + return; + } + + napi_get_undefined(env, &result[PARAM0]); + if (!context->albumAssets.empty()) { + size_t len = context->albumAssets.size(); + if (napi_create_array(env, &albumArray) == napi_ok) { + size_t i; + for (i = 0; i < len; i++) { + albumAsset = AlbumAssetNapi::CreateAlbumAsset(env, context->albumType, + *(context->albumAssets[i]), *(context->objectInfo->GetMediaLibClientInstance())); + if (albumAsset == nullptr || napi_set_element(env, albumArray, i, albumAsset) != napi_ok) { + HiLog::Error(LABEL, "Failed to get album asset napi object"); + napi_get_undefined(env, &result[PARAM1]); + break; + } + } + if (i == len) { + result[PARAM1] = albumArray; + } + } else { + napi_get_undefined(env, &result[PARAM1]); + } + } else { + HiLog::Error(LABEL, "No album assets found!"); + napi_get_undefined(env, &result[PARAM1]); + } + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; +} + +napi_value MediaLibraryNapi::GetVideoAlbums(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc >= ARGS_ONE, "requires 1 parameter minimum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetVideoAlbums"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->albumAssets = + context->objectInfo->mediaLibrary_->GetVideoAlbumAssets(context->selection, + context->selectionArgs); + context->albumType = TYPE_VIDEO_ALBUM; + context->status = 0; + }, + AlbumAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value MediaLibraryNapi::GetImageAlbums(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + GET_JS_ARGS(env, info, ARGS_TWO); + NAPI_ASSERT(env, argc >= ARGS_ONE, "requires 1 parameter minimum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + if (result == nullptr) { + return result; + } + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "GetImageAlbums"); + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + MediaLibraryAsyncContext* context = static_cast(data); + context->albumAssets = + context->objectInfo->mediaLibrary_->GetImageAlbumAssets(context->selection, + context->selectionArgs); + context->albumType = TYPE_IMAGE_ALBUM; + context->status = 0; + }, + AlbumAssetsAsyncCallbackComplete, static_cast(asyncContext.get()), &asyncContext->work); + if (status != napi_ok) { + napi_get_undefined(env, &result); + } else { + napi_queue_async_work(env, asyncContext->work); + asyncContext.release(); + } + } + + return result; +} + +napi_value GetAssetJSObject(napi_env env, AssetType type, Media::IMediaLibraryClient &mediaLibrary) +{ + napi_value assetObj = nullptr; + + switch (type) { + case TYPE_AUDIO: { + std::unique_ptr audioObj = std::make_unique(); + assetObj = AudioAssetNapi::CreateAudioAsset(env, *(audioObj), mediaLibrary); + break; + } + case TYPE_VIDEO: { + std::unique_ptr videoObj = std::make_unique(); + assetObj = VideoAssetNapi::CreateVideoAsset(env, *(videoObj), mediaLibrary); + break; + } + case TYPE_IMAGE: { + std::unique_ptr imageObj = std::make_unique(); + assetObj = ImageAssetNapi::CreateImageAsset(env, *(imageObj), mediaLibrary); + break; + } + case TYPE_ALBUM: { + std::unique_ptr albumObj = std::make_unique(); + assetObj = AlbumAssetNapi::CreateAlbumAsset(env, TYPE_NONE, *(albumObj), mediaLibrary); + break; + } + default: + HiLog::Error(LABEL, "Wrong media type"); + break; + } + + if (assetObj == nullptr) { + HiLog::Error(LABEL, "No assets obtained"); + napi_get_undefined(env, &assetObj); + } + + return assetObj; +} + +void CreateAssetAsyncCbComplete(napi_env env, napi_status status, void* data) +{ + auto context = static_cast(data); + napi_value result[ARGS_TWO] = {0}; + + if (context != nullptr) { + napi_get_undefined(env, &result[PARAM0]); + result[PARAM1] = GetAssetJSObject(env, context->assetType, + *(context->objectInfo->GetMediaLibClientInstance())); + + if (context->work != nullptr) { + MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, result, ARGS_TWO, + context->callbackRef, context->work); + } + delete context; + } else { + HiLog::Error(LABEL, "Async context is null"); + } +} + +void CreateAsyncWork(napi_env env, napi_value resource, + const MediaLibraryAsyncContext& mediaLibContext, + AssetType type, bool &err) +{ + napi_status status; + MediaLibraryAsyncContext* asyncContext = const_cast(&mediaLibContext); + asyncContext->assetType = type; + + status = napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) {}, + CreateAssetAsyncCbComplete, (void*)asyncContext, &asyncContext->work); + if (status != napi_ok) { + err = true; + } else { + napi_queue_async_work(env, asyncContext->work); + } +} + +napi_value MediaLibraryNapi::CreateAudioAsset(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + bool err = false; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + ASSERT_NULLPTR_CHECK(env, result); + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CreateAudioAsset"); + + CreateAsyncWork(env, resource, *(asyncContext.get()), TYPE_AUDIO, err); + if (!err) { + asyncContext.release(); + } else { + napi_get_undefined(env, &result); + } + } + + return result; +} + +napi_value MediaLibraryNapi::CreateVideoAsset(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + bool err = false; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + ASSERT_NULLPTR_CHECK(env, result); + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CreateVideoAsset"); + + CreateAsyncWork(env, resource, *(asyncContext.get()), TYPE_VIDEO, err); + if (!err) { + asyncContext.release(); + } else { + napi_get_undefined(env, &result); + } + } + + return result; +} + +napi_value MediaLibraryNapi::CreateImageAsset(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + bool err = false; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + ASSERT_NULLPTR_CHECK(env, result); + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CreateImageAsset"); + + CreateAsyncWork(env, resource, *(asyncContext.get()), TYPE_IMAGE, err); + if (!err) { + asyncContext.release(); + } else { + napi_get_undefined(env, &result); + } + } + + return result; +} + +napi_value MediaLibraryNapi::CreateAlbum(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + bool err = false; + + GET_JS_ARGS(env, info, ARGS_ONE); + NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum"); + + napi_get_undefined(env, &result); + std::unique_ptr asyncContext = std::make_unique(); + status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->objectInfo)); + if (status == napi_ok && asyncContext->objectInfo != nullptr) { + result = ConvertJSArgsToNative(env, argc, argv, *asyncContext); + ASSERT_NULLPTR_CHECK(env, result); + + NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result); + NAPI_CREATE_RESOURCE_NAME(env, "CreateAlbum"); + + CreateAsyncWork(env, resource, *(asyncContext.get()), TYPE_ALBUM, err); + if (!err) { + asyncContext.release(); + } else { + napi_get_undefined(env, &result); + } + } + + return result; +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/native_module_ohos_medialibrary.cpp b/frameworks/kitsimpl/medialibrary/src/native_module_ohos_medialibrary.cpp new file mode 100644 index 0000000000..e7474049f8 --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/native_module_ohos_medialibrary.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_module_ohos_medialibrary.h" + +namespace OHOS { +/* + * Function registering all props and functions of ohos.medialibrary module + */ +static napi_value Export(napi_env env, napi_value exports) +{ + MediaAssetNapi::Init(env, exports); + AudioAssetNapi::Init(env, exports); + VideoAssetNapi::Init(env, exports); + ImageAssetNapi::Init(env, exports); + AlbumAssetNapi::Init(env, exports); + MediaLibraryNapi::Init(env, exports); + + return exports; +} + +/* + * module define + */ +static napi_module g_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Export, + .nm_modname = "multimedia.medialibrary", + .nm_priv = ((void*)0), + .reserved = {0} +}; + +/* + * module register + */ +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&g_module); +} +} // namespace OHOS diff --git a/frameworks/kitsimpl/medialibrary/src/video_asset_napi.cpp b/frameworks/kitsimpl/medialibrary/src/video_asset_napi.cpp new file mode 100644 index 0000000000..e2f5a003dd --- /dev/null +++ b/frameworks/kitsimpl/medialibrary/src/video_asset_napi.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "video_asset_napi.h" +#include "hilog/log.h" + +using OHOS::HiviewDFX::HiLog; +using OHOS::HiviewDFX::HiLogLabel; + +namespace { + constexpr HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "VideoAssetNapi"}; + const int32_t DEFAULT_VIDEO_WIDTH = 1280; + const int32_t DEFAULT_VIDEO_HEIGHT = 720; + const int32_t DEFAULT_VIDEO_DURATION = 0; + const std::string DEFAULT_VIDEO_MIME_TYPE = "video/*"; +} + +namespace OHOS { +napi_ref VideoAssetNapi::sConstructor_ = nullptr; +Media::VideoAsset *VideoAssetNapi::sVideoAsset_ = nullptr; +Media::IMediaLibraryClient *VideoAssetNapi::sMediaLibrary_ = nullptr; + +VideoAssetNapi::VideoAssetNapi() + : env_(nullptr), wrapper_(nullptr) +{ + width_ = DEFAULT_VIDEO_WIDTH; + height_ = DEFAULT_VIDEO_HEIGHT; + duration_ = DEFAULT_VIDEO_DURATION; + mimeType_ = DEFAULT_VIDEO_MIME_TYPE; +} + +VideoAssetNapi::~VideoAssetNapi() +{ + if (wrapper_ != nullptr) { + napi_delete_reference(env_, wrapper_); + } +} + +void VideoAssetNapi::VideoAssetNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + VideoAssetNapi *video = reinterpret_cast(nativeObject); + if (video != nullptr) { + video->~VideoAssetNapi(); + } +} + +napi_value VideoAssetNapi::Init(napi_env env, napi_value exports) +{ + napi_status status; + napi_value ctorObj; + int32_t refCount = 1; + + napi_property_descriptor video_asset_props[] = { + DECLARE_NAPI_GETTER("mimeType", GetMimeType), + DECLARE_NAPI_GETTER("width", GetWidth), + DECLARE_NAPI_GETTER("height", GetHeight), + DECLARE_NAPI_GETTER("duration", GetDuration), + DECLARE_NAPI_GETTER("id", GetId), + DECLARE_NAPI_GETTER("URI", GetUri), + DECLARE_NAPI_GETTER("mediaType", GetMediaType), + DECLARE_NAPI_GETTER("size", GetSize), + DECLARE_NAPI_GETTER("dateAdded", GetDateAdded), + DECLARE_NAPI_GETTER("dateModified", GetDateModified), + DECLARE_NAPI_GETTER("albumId", GetAlbumId), + DECLARE_NAPI_GETTER_SETTER("albumName", GetAlbumName, JSSetAlbumName), + DECLARE_NAPI_GETTER_SETTER("name", GetName, JSSetName), + DECLARE_NAPI_FUNCTION("startCreate", StartCreate), + DECLARE_NAPI_FUNCTION("cancelCreate", CancelCreate), + DECLARE_NAPI_FUNCTION("commitCreate", CommitCreate), + DECLARE_NAPI_FUNCTION("startModify", StartModify), + DECLARE_NAPI_FUNCTION("cancelModify", CancelModify), + DECLARE_NAPI_FUNCTION("commitModify", CommitModify), + DECLARE_NAPI_FUNCTION("commitDelete", CommitDelete), + DECLARE_NAPI_FUNCTION("commitCopy", CommitCopy), + }; + + status = napi_define_class(env, VIDEO_ASSET_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, + VideoAssetNapiConstructor, nullptr, + sizeof(video_asset_props) / sizeof(video_asset_props[PARAM0]), + video_asset_props, &ctorObj); + if (status == napi_ok) { + status = napi_create_reference(env, ctorObj, refCount, &sConstructor_); + if (status == napi_ok) { + status = napi_set_named_property(env, exports, VIDEO_ASSET_NAPI_CLASS_NAME.c_str(), ctorObj); + if (status == napi_ok) { + return exports; + } + } + } + + return nullptr; +} + +// Constructor callback +napi_value VideoAssetNapi::VideoAssetNapiConstructor(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value result = nullptr; + + napi_get_undefined(env, &result); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status == napi_ok && thisVar != nullptr) { + std::unique_ptr obj = std::make_unique(); + if (obj != nullptr) { + obj->env_ = env; + obj->SetMediaLibraryClient(*sMediaLibrary_); + if (sVideoAsset_ != nullptr) { + obj->UpdateVideoAssetInfo(); + } else { + HiLog::Error(LABEL, "No native instance assigned yet"); + return result; + } + + status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), + VideoAssetNapi::VideoAssetNapiDestructor, nullptr, &(obj->wrapper_)); + if (status == napi_ok) { + obj.release(); + return thisVar; + } else { + HiLog::Error(LABEL, "Failure wrapping js to native napi"); + } + } + } + + return result; +} + +napi_value VideoAssetNapi::CreateVideoAsset(napi_env env, Media::VideoAsset &vAsset, + Media::IMediaLibraryClient &mediaLibClient) +{ + napi_status status; + napi_value result = nullptr; + napi_value constructor; + + status = napi_get_reference_value(env, sConstructor_, &constructor); + if (status == napi_ok) { + sVideoAsset_ = &vAsset; + sMediaLibrary_ = &mediaLibClient; + status = napi_new_instance(env, constructor, 0, nullptr, &result); + sVideoAsset_ = nullptr; + if (status == napi_ok && result != nullptr) { + return result; + } else { + HiLog::Error(LABEL, "Failed to create video asset instance"); + } + } + + napi_get_undefined(env, &result); + return result; +} + +napi_value VideoAssetNapi::GetMimeType(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + VideoAssetNapi* obj = nullptr; + std::string mimeType = ""; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + mimeType = obj->mimeType_; + status = napi_create_string_utf8(env, mimeType.c_str(), NAPI_AUTO_LENGTH, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value VideoAssetNapi::GetWidth(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + VideoAssetNapi* obj = nullptr; + int32_t width; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + width = obj->width_; + status = napi_create_int32(env, width, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value VideoAssetNapi::GetHeight(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + VideoAssetNapi* obj = nullptr; + int32_t height; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + height = obj->height_; + status = napi_create_int32(env, height, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +napi_value VideoAssetNapi::GetDuration(napi_env env, napi_callback_info info) +{ + napi_status status; + napi_value jsResult = nullptr; + napi_value undefinedResult = nullptr; + VideoAssetNapi* obj = nullptr; + int32_t duration; + + napi_get_undefined(env, &undefinedResult); + GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status); + if (status != napi_ok || thisVar == nullptr) { + HiLog::Error(LABEL, "Invalid arguments!"); + return undefinedResult; + } + + status = napi_unwrap(env, thisVar, reinterpret_cast(&obj)); + if (status == napi_ok && obj != nullptr) { + duration = obj->duration_; + status = napi_create_int32(env, duration, &jsResult); + if (status == napi_ok) { + return jsResult; + } + } + + return undefinedResult; +} + +void VideoAssetNapi::UpdateVideoAssetInfo() +{ + this->SetId(sVideoAsset_->id_); + this->SetUri(sVideoAsset_->uri_); + this->SetMediaType(static_cast(sVideoAsset_->mediaType_)); + this->SetName(sVideoAsset_->name_); + this->SetSize(sVideoAsset_->size_); + this->SetDateAdded(sVideoAsset_->dateAdded_); + this->SetDateModified(sVideoAsset_->dateModified_); + this->SetAlbumName(sVideoAsset_->albumName_); + this->SetAlbumId(sVideoAsset_->albumId_); + mimeType_ = sVideoAsset_->mimeType_; + width_ = sVideoAsset_->width_; + height_ = sVideoAsset_->height_; + duration_ = sVideoAsset_->duration_; +} +} // namespace OHOS diff --git a/interfaces/innerkits/native/include/IMediaLibraryClient.h b/interfaces/innerkits/native/include/IMediaLibraryClient.h new file mode 100644 index 0000000000..78d05b1808 --- /dev/null +++ b/interfaces/innerkits/native/include/IMediaLibraryClient.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMEDIALIBRARYCLIENT_H +#define IMEDIALIBRARYCLIENT_H + +#include "album_asset.h" +#include "audio_asset.h" +#include "image_asset.h" +#include "media_asset.h" +#include "video_asset.h" + +namespace OHOS { +namespace Media { +class IMediaLibraryClient { +public: + virtual ~IMediaLibraryClient() {} + + /** + * @brief Returns the Media Library Instance + * + * @return Returns the Media Library Instance + * @since 1.0 + * @version 1.0 + */ + static IMediaLibraryClient *GetMediaLibraryClientInstance(); + + /** + * @brief Gets list of media assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of media asset unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetMediaAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Gets list of audio assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of audio asset unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetAudioAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Gets list of video assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of video asset unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetVideoAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Gets list of image assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of image asset unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetImageAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Gets list of image asset albums + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of image asset album unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetImageAlbumAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Gets list of video asset albums + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of video asset unique pointers + * @since 1.0 + * @version 1.0 + */ + virtual std::vector> GetVideoAlbumAssets(std::string selection, + std::vector selectionArgs) = 0; + + /** + * @brief Creates Media Asset + * + * @param assetType enum media assetType + * @param mediaAsset MediaAsset class object + * @return Returns status of media asset creation + * @since 1.0 + * @version 1.0 + */ + virtual bool CreateMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) = 0; + + /** + * @brief Delete Media Asset + * + * @param assetType enum media assetType + * @param mediaAsset MediaAsset class object + * @return Returns status of media asset delete + * @since 1.0 + * @version 1.0 + */ + virtual bool DeleteMediaAsset(AssetType assetType, const MediaAsset &mediaAsset) = 0; + + /** + * @brief Modify Media Asset + * + * @param assetType enum media assetType + * @param srcMediaAsset source MediaAsset class object + * @param dstMediaAsset destination MediaAsset class object + * @return Returns status of media asset modification + * @since 1.0 + * @version 1.0 + */ + virtual bool ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) = 0; + + /** + * @brief Copy Media Asset + * + * @param assetType enum media assetType + * @param srcMediaAsset source MediaAsset class object + * @param dstMediaAsset destination MediaAsset class object + * @return Returns status of media asset copy + * @since 1.0 + * @version 1.0 + */ + virtual bool CopyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset) = 0; + + /** + * @brief Creates Media Album Asset + * + * @param assetType enum media assetType + * @param albumAsset AlbumAsset class object + * @return Returns status of creation media album. + * @since 1.0 + * @version 1.0 + */ + virtual bool CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset) = 0; + + /** + * @brief Delete Media Album Asset + * + * @param assetType enum media assetType + * @param albumAsset AlbumAsset class object + * @return Returns status of deleted media album. + * @since 1.0 + * @version 1.0 + */ + virtual bool DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset &albumAsset, + const std::string &albumUri) = 0; + + /** + * @brief Modify Media Album Asset + * + * @param assetType enum media assetType + * @param srcAlbumAsset source AlbumAsset class object + * @param dstAlbumAsset destination AlbumAsset class object + * @return Returns status of media album modification + * @since 1.0 + * @version 1.0 + */ + virtual bool ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset &srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const std::string &albumUri) = 0; +}; +} // namespace Media +} // namespace OHOS +#endif // IMEDIALIBRARYCLIENT_H diff --git a/interfaces/innerkits/native/include/album_asset.h b/interfaces/innerkits/native/include/album_asset.h new file mode 100644 index 0000000000..90a0a4c907 --- /dev/null +++ b/interfaces/innerkits/native/include/album_asset.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ALBUM_H +#define ALBUM_H + +#include +#include + +#include "audio_asset.h" +#include "image_asset.h" +#include "video_asset.h" + +namespace OHOS { +namespace Media { +/** + * @brief Data class for album details + * + * @since 1.0 + * @version 1.0 + */ +class AlbumAsset { +public: + AlbumAsset(); + virtual ~AlbumAsset(); + + bool CreateAlbumAsset(); + bool DeleteAlbumAsset(const std::string &albumUri); + bool ModifyAlbumAsset(const AlbumAsset &albumAsset, const std::string &albumUri); + + int32_t albumId_; + std::string albumName_; + std::vector> imageAssetList_; + std::vector> videoAssetList_; +}; +} // namespace Media +} // namespace OHOS +#endif // ALBUM_H diff --git a/interfaces/innerkits/native/include/audio_asset.h b/interfaces/innerkits/native/include/audio_asset.h new file mode 100644 index 0000000000..2bf07776ba --- /dev/null +++ b/interfaces/innerkits/native/include/audio_asset.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_ASSET_H +#define AUDIO_ASSET_H + +#include "media_asset.h" + +namespace OHOS { +namespace Media { +/** + * @brief Data class for audio file details + * + * @since 1.0 + * @version 1.0 + */ +class AudioAsset : public MediaAsset { +public: + AudioAsset(); + virtual ~AudioAsset(); + + int32_t duration_; + std::string title_; + std::string artist_; + std::string mimeType_; +}; +} // namespace Media +} // namespace OHOS +#endif // AUDIO_ASSET_H diff --git a/interfaces/innerkits/native/include/image_asset.h b/interfaces/innerkits/native/include/image_asset.h new file mode 100644 index 0000000000..87278eb3cb --- /dev/null +++ b/interfaces/innerkits/native/include/image_asset.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMAGE_ASSET_H +#define IMAGE_ASSET_H + +#include "media_asset.h" + +namespace OHOS { +namespace Media { +/** + * @brief Data class for image file details + * + * @since 1.0 + * @version 1.0 + */ +class ImageAsset : public MediaAsset { +public: + ImageAsset(); + virtual ~ImageAsset(); + + int32_t width_; + int32_t height_; + std::string mimeType_; +}; +} // namespace Media +} // namespace OHOS +#endif // IMAGE_ASSET_H diff --git a/interfaces/innerkits/native/include/media_asset.h b/interfaces/innerkits/native/include/media_asset.h new file mode 100644 index 0000000000..7e511f1ed5 --- /dev/null +++ b/interfaces/innerkits/native/include/media_asset.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_ASSET_H +#define MEDIA_ASSET_H + +#include +#include +#include +#include +#include + +#include "media_lib_service_const.h" + +namespace OHOS { +namespace Media { +/** + * @brief Data class for media file details + * + * @since 1.0 + * @version 1.0 + */ +class MediaAsset { +public: + MediaAsset(); + virtual ~MediaAsset(); + bool CreateMediaAsset(AssetType assetType); + bool DeleteMediaAsset(); + bool ModifyMediaAsset(const MediaAsset &mediaAsset); + bool CopyMediaAsset(const MediaAsset &mediaAsset); + static MediaType GetMediaType(const std::string &filePath); + + int32_t id_; + uint64_t size_; + int32_t albumId_; + std::string albumName_; + std::string uri_; + MediaType mediaType_; + std::string name_; + uint64_t dateAdded_; + uint64_t dateModified_; +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_ASSET_H diff --git a/interfaces/innerkits/native/include/media_lib_service_const.h b/interfaces/innerkits/native/include/media_lib_service_const.h new file mode 100644 index 0000000000..a4e7f13081 --- /dev/null +++ b/interfaces/innerkits/native/include/media_lib_service_const.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIB_SERVICE_CONST_H +#define MEDIA_LIB_SERVICE_CONST_H + +#include + +namespace OHOS { +namespace Media { +enum { + MEDIA_GET_MEDIA_ASSETS = 0, + MEDIA_GET_IMAGE_ASSETS = 1, + MEDIA_GET_AUDIO_ASSETS = 2, + MEDIA_GET_VIDEO_ASSETS = 3, + MEDIA_GET_IMAGEALBUM_ASSETS = 4, + MEDIA_GET_VIDEOALBUM_ASSETS = 5, + MEDIA_CREATE_MEDIA_ASSET = 6, + MEDIA_DELETE_MEDIA_ASSET = 7, + MEDIA_MODIFY_MEDIA_ASSET = 8, + MEDIA_COPY_MEDIA_ASSET = 9, + MEDIA_CREATE_MEDIA_ALBUM_ASSET = 10, + MEDIA_DELETE_MEDIA_ALBUM_ASSET = 11, + MEDIA_MODIFY_MEDIA_ALBUM_ASSET = 12, +}; + +enum MediaType { + MEDIA_TYPE_DEFAULT = 0, + MEDIA_TYPE_FILE, + MEDIA_TYPE_MEDIA, + MEDIA_TYPE_IMAGE, + MEDIA_TYPE_VIDEO, + MEDIA_TYPE_AUDIO, + MEDIA_TYPE_ALBUM_LIST, + MEDIA_TYPE_ALBUM_LIST_INFO +}; + +/* ENUM Asset types */ +enum AssetType { + ASSET_MEDIA = 0, + ASSET_IMAGE, + ASSET_AUDIO, + ASSET_VIDEO, + ASSET_GENERIC_ALBUM, + ASSET_IMAGEALBUM, + ASSET_VIDEOALBUM, + ASSET_NONE +}; + +const int32_t SUCCESS = 0; +const int32_t FAIL = -1; + +const int32_t MEDIA_ASSET_READ_FAIL = 1; +const int32_t IMAGE_ASSET_READ_FAIL = 2; +const int32_t AUDIO_ASSET_READ_FAIL = 3; +const int32_t VIDEO_ASSET_READ_FAIL = 4; +const int32_t IMAGEALBUM_ASSET_READ_FAIL = 5; +const int32_t VIDEOALBUM_ASSET_READ_FAIL = 6; + +const int32_t MEDIA_ASSET_WRITE_FAIL = 7; +const int32_t IMAGE_ASSET_WRITE_FAIL = 8; +const int32_t AUDIO_ASSET_WRITE_FAIL = 9; +const int32_t VIDEO_ASSET_WRITE_FAIL = 10; +const int32_t IMAGEALBUM_ASSET_WRITE_FAIL = 11; +const int32_t VIDEOALBUM_ASSET_WRITE_FAIL = 12; +const int32_t ALBUM_ASSET_WRITE_FAIL = 13; +const int32_t COMMON_DATA_WRITE_FAIL = 14; +const int32_t COMMON_DATA_READ_FAIL = 15; + +const int32_t DEFAULT_MEDIA_ID = 0; +const int32_t DEFAULT_ALBUM_ID = 0; +const uint64_t DEFAULT_MEDIA_SIZE = 0; +const uint64_t DEFAULT_MEDIA_DATE_ADDED = 0; +const uint64_t DEFAULT_MEDIA_DATE_MODIFIED = 0; +const std::string DEFAULT_MEDIA_URI = ""; +const MediaType DEFAULT_MEDIA_TYPE = MEDIA_TYPE_FILE; +const std::string DEFAULT_MEDIA_NAME = "Unknown"; +const std::string DEFAULT_ALBUM_NAME = "Unknown"; +const std::string ROOT_MEDIA_DIR = "/data/media"; +const char SLASH_CHAR = '/'; +const int OPEN_FDS = 64; +const int32_t MILLISECONDS = 1000; +const char DOT_CHAR = '.'; + +/** Supported audio container types */ +const std::string AUDIO_CONTAINER_TYPE_AAC = "aac"; +const std::string AUDIO_CONTAINER_TYPE_MP3 = "mp3"; +const std::string AUDIO_CONTAINER_TYPE_FLAC = "flac"; +const std::string AUDIO_CONTAINER_TYPE_WAV = "wav"; + +/** Supported video container types */ +const std::string VIDEO_CONTAINER_TYPE_MP4 = "mp4"; +const std::string VIDEO_CONTAINER_TYPE_3GP = "3gp"; +const std::string VIDEO_CONTAINER_TYPE_MPG = "mpg"; +const std::string VIDEO_CONTAINER_TYPE_MOV = "mov"; +const std::string VIDEO_CONTAINER_TYPE_WEBM = "webm"; + +/** Supported image types */ +const std::string IMAGE_CONTAINER_TYPE_BMP = "bmp"; +const std::string IMAGE_CONTAINER_TYPE_GIF = "gif"; +const std::string IMAGE_CONTAINER_TYPE_JPG = "jpg"; +const std::string IMAGE_CONTAINER_TYPE_PNG = "png"; + +// Unordered set contains list supported audio formats +const std::unordered_set SUPPORTED_AUDIO_FORMATS_SET { + AUDIO_CONTAINER_TYPE_AAC, + AUDIO_CONTAINER_TYPE_MP3, + AUDIO_CONTAINER_TYPE_FLAC, + AUDIO_CONTAINER_TYPE_WAV + }; + +// Unordered set contains list supported video formats +const std::unordered_set SUPPORTED_VIDEO_FORMATS_SET { + VIDEO_CONTAINER_TYPE_MP4, + VIDEO_CONTAINER_TYPE_3GP, + VIDEO_CONTAINER_TYPE_MPG, + VIDEO_CONTAINER_TYPE_MOV, + VIDEO_CONTAINER_TYPE_WEBM + }; + +// Unordered set contains list supported image formats +const std::unordered_set SUPPORTED_IMAGE_FORMATS_SET { + IMAGE_CONTAINER_TYPE_BMP, + IMAGE_CONTAINER_TYPE_GIF, + IMAGE_CONTAINER_TYPE_JPG, + IMAGE_CONTAINER_TYPE_PNG + }; +} // namespace OHOS +} // namespace Media +#endif // MEDIA_LIB_SERVICE_CONST_H diff --git a/interfaces/innerkits/native/include/media_library.h b/interfaces/innerkits/native/include/media_library.h new file mode 100644 index 0000000000..bbb3fb8175 --- /dev/null +++ b/interfaces/innerkits/native/include/media_library.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIBRARY_H +#define MEDIA_LIBRARY_H + +#include "album_asset.h" +#include "audio_asset.h" +#include "image_asset.h" +#include "media_asset.h" +#include "video_asset.h" + +namespace OHOS { +namespace Media { +/** Media scan operation success */ +const int32_t MEDIA_SCAN_SUCCESS = 0; +/** Media scan operation failed */ +const int32_t MEDIA_SCAN_FAIL = -1; + +/** + * @brief Media library class + * + * @since 1.0 + * @version 1.0 + */ +class MediaLibrary { +public: + MediaLibrary(); + virtual ~MediaLibrary(); + + /** + * Creates an instance for media livrary. + * + * @return a new Media Library unique pointer. + */ + static std::unique_ptr GetMediaLibraryInstance(); + + /** + * @brief Gets list of media assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of media asset unique pointers + * @since 1.0 + * @version 1.0 + */ + std::vector> GetMediaAssets(std::string selection, + std::vector selectionArgs); + + /** + * @brief Gets list of audio assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of audio asset unique pointers + * @since 1.0 + * @version 1.0 + */ + std::vector> GetAudioAssets(std::string selection, + std::vector selectionArgs); + + /** + * @brief Gets list of video assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of video asset unique pointers + * @since 1.0 + * @version 1.0 + */ + std::vector> GetVideoAssets(std::string selection, + std::vector selectionArgs); + + /** + * @brief Gets list of image assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of image asset unique pointers + * @since 1.0 + * @version 1.0 + */ + std::vector> GetImageAssets(std::string selection, + std::vector selectionArgs); + + /** + * @brief Gets list of image album assets + * + * @param selection Selection string + * @param selectionArgs Selection argument + * @return Returns vector of image asset album unique pointers + * @since 1.0 + * @version 1.0 + */ + std::vector> GetAlbumAssets(std::string selection, + std::vector selectionArgs, + int32_t requestType); + + /** + * @brief Creates Media Asset + * + * @param assetType enum media assetType + * @param mediaAsset MediaAsset class object + * @return Returns status of creation + * @since 1.0 + * @version 1.0 + */ + bool CreateMediaAsset(AssetType assetType, const MediaAsset& mediaAsset); + + /** + * @brief Delete Media Asset + * + * @param assetType enum media assetType + * @param mediaAsset MediaAsset class object + * @return Returns status of delete + * @since 1.0 + * @version 1.0 + */ + bool DeleteMediaAsset(AssetType assetType, const MediaAsset& mediaAsset); + + /** + * @brief Modify Media Asset + * + * @param assetType enum media assetType + * @param srcMediaAsset source MediaAsset class object + * @param dstMediaAsset destination MediaAsset class object + * @return Returns status of file modification + * @since 1.0 + * @version 1.0 + */ + bool ModifyMediaAsset(AssetType assetType, const MediaAsset &srcMediaAsset, + const MediaAsset &dstMediaAsset); + + /** + * @brief Copy Media Asset + * + * @param assetType enum media assetType + * @param srcMediaAsset source MediaAsset class object + * @param dstMediaAsset destination MediaAsset class object + * @return Returns status of media copy + * @since 1.0 + * @version 1.0 + */ + bool CopyMediaAsset(AssetType assetType, const MediaAsset& srcMediaAsset, + const MediaAsset& dstMediaAsset); + + /** + * @brief Creates Media Album Asset + * + * @param assetType enum media assetType + * @param albumAsset AlbumAsset class object + * @return Returns status of creation media album. + * @since 1.0 + * @version 1.0 + */ + bool CreateMediaAlbumAsset(AssetType assetType, const AlbumAsset& albumAsset); + + /** + * @brief Delete Media Album Asset + * + * @param assetType enum media assetType + * @param albumAsset AlbumAsset class object + * @return Returns status of deleted media album. + * @since 1.0 + * @version 1.0 + */ + bool DeleteMediaAlbumAsset(AssetType assetType, const AlbumAsset& albumAsset, + const std::string &albumUri); + + /** + * @brief Modify Media Album Asset + * + * @param assetType enum media assetType + * @param srcAlbumAsset source AlbumAsset class object + * @param dstAlbumAsset destination AlbumAsset class object + * @return Returns status of media album modification + * @since 1.0 + * @version 1.0 + */ + bool ModifyMediaAlbumAsset(AssetType assetType, const AlbumAsset& srcAlbumAsset, + const AlbumAsset &dstAlbumAsset, const std::string &albumUri); +}; +} // namespace Media +} // namespace OHOS +#endif // MEDIA_LIBRARY_H diff --git a/interfaces/innerkits/native/include/media_log.h b/interfaces/innerkits/native/include/media_log.h new file mode 100644 index 0000000000..aa1227dfc0 --- /dev/null +++ b/interfaces/innerkits/native/include/media_log.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEDIA_LOG_H +#define OHOS_MEDIA_LOG_H + +#include +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD002B00 +#define LOG_TAG "MultiMedia:MediaLibrary" + +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#ifndef OHOS_DEBUG +#define DECORATOR_HILOG(op, fmt, args...) \ + do { \ + op(LOG_CORE, fmt, ##args); \ + } while (0) +#else +#define DECORATOR_HILOG(op, fmt, args...) \ + do { \ + op(LOG_CORE, "{%s()-%s:%d} " fmt, __FUNCTION__, __FILENAME__, __LINE__, ##args); \ + } while (0) +#endif + +#define MEDIA_DEBUG_LOG(fmt, ...) DECORATOR_HILOG(HILOG_DEBUG, fmt, ##__VA_ARGS__) +#define MEDIA_ERR_LOG(fmt, ...) DECORATOR_HILOG(HILOG_ERROR, fmt, ##__VA_ARGS__) +#define MEDIA_WARNING_LOG(fmt, ...) DECORATOR_HILOG(HILOG_WARN, fmt, ##__VA_ARGS__) +#define MEDIA_INFO_LOG(fmt, ...) DECORATOR_HILOG(HILOG_INFO, fmt, ##__VA_ARGS__) +#define MEDIA_FATAL_LOG(fmt, ...) DECORATOR_HILOG(HILOG_FATAL, fmt, ##__VA_ARGS__) + +#define MEDIA_OK 0 +#define MEDIA_INVALID_PARAM (-1) +#define MEDIA_INIT_FAIL (-2) +#define MEDIA_ERR (-3) +#define MEDIA_PERMISSION_DENIED (-4) + +#endif // OHOS_MEDIA_LOG_H diff --git a/interfaces/innerkits/native/include/video_asset.h b/interfaces/innerkits/native/include/video_asset.h new file mode 100644 index 0000000000..2651185301 --- /dev/null +++ b/interfaces/innerkits/native/include/video_asset.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIDEO_ASSET_H +#define VIDEO_ASSET_H + +#include "media_asset.h" + +namespace OHOS { +namespace Media { +/** + * @brief Data class for video file details + * + * @since 1.0 + * @version 1.0 + */ +class VideoAsset : public MediaAsset { +public: + VideoAsset(); + virtual ~VideoAsset(); + + int32_t width_; + int32_t height_; + int32_t duration_; + std::string mimeType_; +}; +} // namespace Media +} // namespace OHOS +#endif // VIDEO_ASSET_H diff --git a/interfaces/innerkits/native/test/media_library_test.cpp b/interfaces/innerkits/native/test/media_library_test.cpp new file mode 100644 index 0000000000..e640249ceb --- /dev/null +++ b/interfaces/innerkits/native/test/media_library_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "media_library.h" +#include "media_log.h" + +using namespace std; +using namespace OHOS::Media; + +namespace MediaLibTest { + const int SECOND_ARG_IDX = 2; +} + +class MediaLibraryTest { +public: + void TestGetAssets(const string &selection) const + { + unique_ptr mediaLibrary = MediaLibrary::GetMediaLibraryInstance(); + vector selectionArgs; + + MEDIA_DEBUG_LOG("Media assets:"); + vector> mediaAssets + = mediaLibrary->GetMediaAssets(selection, selectionArgs); + for (size_t i = 0; i < mediaAssets.size(); i++) { + MEDIA_DEBUG_LOG("%{public}s", mediaAssets[i]->uri_.c_str()); + } + + MEDIA_DEBUG_LOG("Audio assets:"); + vector> audioAssets + = mediaLibrary->GetAudioAssets(selection, selectionArgs); + for (size_t i = 0; i < audioAssets.size(); i++) { + MEDIA_DEBUG_LOG("%{public}s", audioAssets[i]->uri_.c_str()); + } + + MEDIA_DEBUG_LOG("Video assets:"); + vector> videoAssets + = mediaLibrary->GetVideoAssets(selection, selectionArgs); + for (size_t i = 0; i < videoAssets.size(); i++) { + MEDIA_DEBUG_LOG("%{public}s", videoAssets[i]->uri_.c_str()); + } + + MEDIA_DEBUG_LOG("Image assets:"); + vector> imageAssets + = mediaLibrary->GetImageAssets(selection, selectionArgs); + MEDIA_DEBUG_LOG("Image assets size:%{public}d", imageAssets.size()); + for (size_t i = 0; i < imageAssets.size(); i++) { + MEDIA_DEBUG_LOG("uri: %{public}s", imageAssets[i]->uri_.c_str()); + MEDIA_DEBUG_LOG("id: %{public}d", imageAssets[i]->id_); + MEDIA_DEBUG_LOG("size: %{public}lld", imageAssets[i]->size_); + MEDIA_DEBUG_LOG("media type: %{public}d", imageAssets[i]->mediaType_); + MEDIA_DEBUG_LOG("mime type: %{public}s", imageAssets[i]->mimeType_.c_str()); + MEDIA_DEBUG_LOG("name: %{public}s", imageAssets[i]->name_.c_str()); + MEDIA_DEBUG_LOG("date added: %{public}lld", imageAssets[i]->dateAdded_); + MEDIA_DEBUG_LOG("date modified: %{public}lld", imageAssets[i]->dateModified_); + } + } + + void TestGetAlbums(const string &selection) const + { + unique_ptr mediaLibrary = MediaLibrary::GetMediaLibraryInstance(); + vector selectionArgs; + int32_t requestType = (int32_t)MediaType::MEDIA_TYPE_VIDEO; + vector> albumAssets + = mediaLibrary->GetAlbumAssets(selection, selectionArgs, requestType); + MEDIA_DEBUG_LOG("Album assets size:%{public}d", albumAssets.size()); + for (size_t i = 0; i < albumAssets.size(); i++) { + MEDIA_DEBUG_LOG("Album name:%{public}s", albumAssets[i]->albumName_.c_str()); + MEDIA_DEBUG_LOG("Image album assets:"); + for (size_t j = 0; j < albumAssets[i]->imageAssetList_.size(); j++) { + MEDIA_DEBUG_LOG("uri: %{public}s", albumAssets[i]->imageAssetList_[j]->uri_.c_str()); + MEDIA_DEBUG_LOG("id: %{public}d", albumAssets[i]->imageAssetList_[j]->id_); + MEDIA_DEBUG_LOG("size: %{public}lld", albumAssets[i]->imageAssetList_[j]->size_); + MEDIA_DEBUG_LOG("width: %{public}d", albumAssets[i]->imageAssetList_[j]->width_); + MEDIA_DEBUG_LOG("height: %{public}d", albumAssets[i]->imageAssetList_[j]->height_); + MEDIA_DEBUG_LOG("media type: %{public}d", + albumAssets[i]->imageAssetList_[j]->mediaType_); + MEDIA_DEBUG_LOG("mime type: %{public}s", + albumAssets[i]->imageAssetList_[j]->mimeType_.c_str()); + MEDIA_DEBUG_LOG("name: %{public}s", albumAssets[i]->imageAssetList_[j]->name_.c_str()); + MEDIA_DEBUG_LOG("added: %{public}lld", + albumAssets[i]->imageAssetList_[j]->dateAdded_); + MEDIA_DEBUG_LOG("modified: %{public}lld", + albumAssets[i]->imageAssetList_[j]->dateModified_); + } + + MEDIA_DEBUG_LOG("Video album assets:"); + for (size_t k = 0; k < albumAssets[i]->videoAssetList_.size(); k++) { + MEDIA_DEBUG_LOG("uri: %{public}s", albumAssets[i]->videoAssetList_[k]->uri_.c_str()); + MEDIA_DEBUG_LOG("id: %{public}d", albumAssets[i]->videoAssetList_[k]->id_); + MEDIA_DEBUG_LOG("size: %{public}lld", albumAssets[i]->videoAssetList_[k]->size_); + MEDIA_DEBUG_LOG("width: %{public}d", albumAssets[i]->videoAssetList_[k]->width_); + MEDIA_DEBUG_LOG("height: %{public}d", albumAssets[i]->videoAssetList_[k]->height_); + MEDIA_DEBUG_LOG("duration: %{public}d", albumAssets[i]->videoAssetList_[k]->duration_); + MEDIA_DEBUG_LOG("media type: %{public}d", + albumAssets[i]->videoAssetList_[k]->mediaType_); + MEDIA_DEBUG_LOG("mime type: %{public}s", + albumAssets[i]->videoAssetList_[k]->mimeType_.c_str()); + MEDIA_DEBUG_LOG("name: %{public}s", albumAssets[i]->videoAssetList_[k]->name_.c_str()); + MEDIA_DEBUG_LOG("added: %{public}lld", + albumAssets[i]->videoAssetList_[k]->dateAdded_); + MEDIA_DEBUG_LOG("modified: %{public}lld", + albumAssets[i]->videoAssetList_[k]->dateModified_); + } + } + } + + void TestMediaLibAPI(const string &selection) const + { + MEDIA_INFO_LOG("TestMediaLibAPI start"); + TestGetAssets(selection); + TestGetAlbums(selection); + MEDIA_INFO_LOG("TestMediaLibAPI end"); + } +}; + +int main(int argc, const char *argv[]) +{ + MEDIA_INFO_LOG("media lib test in"); + + if (argv == nullptr) { + MEDIA_ERR_LOG("argv is null"); + return 0; + } + + MEDIA_DEBUG_LOG("argc=%d, argv[0]=%s", argc, argv[0]); + string selection = ""; + if (argc == MediaLibTest::SECOND_ARG_IDX) { + selection = argv[MediaLibTest::SECOND_ARG_IDX - 1]; + } + MediaLibraryTest testObj; + testObj.TestMediaLibAPI(selection); + + return 0; +} diff --git a/interfaces/kits/js/medialibrary/@ohos.multimedia.medialibrary.d.ts b/interfaces/kits/js/medialibrary/@ohos.multimedia.medialibrary.d.ts new file mode 100644 index 0000000000..2da21f198b --- /dev/null +++ b/interfaces/kits/js/medialibrary/@ohos.multimedia.medialibrary.d.ts @@ -0,0 +1,363 @@ +/* + * 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 { AsyncCallback } from './basic'; + +declare namespace mediaLibrary { + + /** + * Returns an instance of MediaLibraryHelper + * + * @return Instance of MediaLibraryHelper + * @version1 + */ + function getMediaLibraryHelper(): MediaLibraryHelper; + + /** + * Enumeration types for different kind of Media Files + * + * @version1 + */ + enum MediaType { + DEFAULT = 0, + FILE, + MEDIA, + IMAGE, + VIDEO, + AUDIO, + ALBUM_LIST, + ALBUM_LIST_INFO + } + + /** + * Defines the media asset. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export interface MediaAsset { + id: number; + URI: string; + mediaType: MediaType; + name: string; + size: number; + dateAdded: number; + dateModified: number; + albumId: number; + albumName: string; + + /** + * Start setting the properties for a newly created media asset + * + * @return Returns whether property setting can be started for a created media asset + * @version 1 + */ + startCreate(callback: AsyncCallback): void; + startCreate(): Promise; + + /** + * Start modifying the properties for an existing media asset + * + * @return Returns whether property modification can be started for a media asset + * @version 1 + */ + startModify(callback: AsyncCallback): void; + startModify(): Promise; + + /** + * Cancel the creation of a media asset + * + * @return Returns whether creation of a media asset was cancelled or not + * @version 1 + */ + cancelCreate(callback: AsyncCallback): void; + cancelCreate(): Promise; + + /** + * Cancel the modification of a media asset + * + * @return Returns whether modification of a media asset was cancelled or not + * @version 1 + */ + cancelModify(callback: AsyncCallback): void; + cancelModify(): Promise; + + /** + * Commit the creation of a media asset + * + * @return Returns whether creation of a media asset was committed or not + * @version 1 + */ + commitCreate(callback: AsyncCallback): void; + commitCreate(): Promise; + + /** + * Delete a media asset + * + * @return Returns whether deletion of a media asset was successful or not + * @version 1 + */ + commitDelete(callback: AsyncCallback): void; + commitDelete(): Promise; + + /** + * Commit the modification of a media asset + * + * @return Returns whether modification of a media asset was committed or not + * @version 1 + */ + commitModify(callback: AsyncCallback): void; + commitModify(): Promise; + + /** + * Copy a media asset properties to the target media asset + * + * @param target The target media asset on which the source properties are to be copied + * @return Returns whether copying of a media asset to the target was successful or not + * @version 1 + */ + commitCopy(target: MediaAsset, callback: AsyncCallback): void; + commitCopy(target: MediaAsset): Promise; + } + + /** + * Defines the audio asset. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export interface AudioAsset extends MediaAsset { + mimeType: string; + title: string; + artist: string; + duration: number; + } + + /** + * Defines the video asset. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export interface VideoAsset extends MediaAsset { + mimeType: string; + width: number; + height: number; + duration: number; + } + + /** + * Defines the image asset. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export interface ImageAsset extends MediaAsset { + mimeType: string; + width: number; + height: number; + } + + /** + * Defines the album. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export interface Album { + albumName : string; + albumId : number; + + /** + * Gets all video assets in album. + * + * @return Returns video assets list as asynchronous response + * @version 1 + */ + getVideoAssets(): Promise; + getVideoAssets(callback: AsyncCallback): void; + + /** + * Gets all image assets in album. + * + * @return Returns image assets list as asynchronous response + * @version 1 + */ + getImageAssets(): Promise; + getImageAssets(callback: AsyncCallback): void; + + /** + * Commit the creation of an album + * + * @return Returns whether creation of an album was committed or not + * @version 1 + */ + commitCreate(callback: AsyncCallback): void; + commitCreate(): Promise; + + /** + * Delete an album + * + * @return Returns whether deletion of an album was successful or not + * @version 1 + */ + commitDelete(callback: AsyncCallback): void; + commitDelete(): Promise; + + /** + * Commit the modification of an album + * + * @return Returns whether modification of an album was committed or not + * @version 1 + */ + commitModify(callback: AsyncCallback): void; + commitModify(): Promise; + } + + /** + * Fetch parameters applicable on images, videos, audios, albums and other media + * + * @version 1 + */ + export interface MediaFetchOptions { + selections: string; + selectionArgs: Array; + } + + type MediaAssets = Array>; + + type AudioAssets = Array>; + + type VideoAssets = Array>; + + type ImageAssets = Array>; + + type Albums = Array>; + + /** + * Defines the MediaLibraryHelper class and provides functions to access the data in media storage. + * + * @SysCap SystemCapability.Multimedia.MediaLibrary + * @devices common + * @version 1 + */ + export class MediaLibraryHelper { + + /** + * Gets all media assets from system. + * + * @param options Fetch options with selection strings based on which to select the media assets + * @return Returns media assets list as asynchronous response + * @version 1 + */ + getMediaAssets(callback: AsyncCallback): void; + getMediaAssets(options: MediaFetchOptions, callback: AsyncCallback): void; + getMediaAssets(options?: MediaFetchOptions): Promise; + + /** + * Gets all audio assets from system. + * + * @param options Fetch options with selection strings based on which to select the audio assets + * @return Returns audio assets list as asynchronous response + * @version 1 + */ + getAudioAssets(callback: AsyncCallback): void; + getAudioAssets(options: MediaFetchOptions, callback: AsyncCallback): void; + getAudioAssets(options?: MediaFetchOptions): Promise; + + /** + * Gets all video assets from system. + * + * @param options Fetch options with selection strings based on which to select the video assets + * @return Returns video assets list as asynchronous response + * @version 1 + */ + getVideoAssets(callback: AsyncCallback): void; + getVideoAssets(options: MediaFetchOptions, callback: AsyncCallback): void; + getVideoAssets(options?: MediaFetchOptions): Promise; + + /** + * Gets all image assets from system. + * + * @param options Fetch options with selection strings based on which to select the image assets + * @return Returns image assets list as asynchronous response + * @version 1 + */ + getImageAssets(callback: AsyncCallback): void; + getImageAssets(options: MediaFetchOptions, callback: AsyncCallback): void; + getImageAssets(options?: MediaFetchOptions): Promise; + + /** + * Gets video album from system + * + * @param options Fetch options with selection strings based on which to select the albums + * @return Returns video album as asynchronous response + * @version 1 + */ + getVideoAlbums(options: MediaFetchOptions, callback: AsyncCallback): void; + getVideoAlbums(options: MediaFetchOptions): Promise; + + /** + * Gets image album from system + * + * @param options Fetch options with selection strings based on which to select the albums + * @return Returns image album as asynchronous response + * @version 1 + */ + getImageAlbums(options: MediaFetchOptions, callback: AsyncCallback): void; + getImageAlbums(options: MediaFetchOptions): Promise; + + /** + * Create a video asset with empty properties + * + * @return Returns a video asset as asynchronous response + * @version 1 + */ + createVideoAsset(callback: AsyncCallback): void; + createVideoAsset(): Promise; + + /** + * Create an image asset with empty properties + * + * @return Returns an image asset as asynchronous response + * @version 1 + */ + createImageAsset(callback: AsyncCallback): void; + createImageAsset(): Promise; + + /** + * Create an audio asset with empty properties + * + * @return Returns an audio asset as asynchronous response + * @version 1 + */ + createAudioAsset(callback: AsyncCallback): void; + createAudioAsset(): Promise; + + /** + * Create an album with empty properties + * + * @return Returns an album as asynchronous response + * @version 1 + */ + createAlbum(callback: AsyncCallback): void; + createAlbum(): Promise; + } +} diff --git a/interfaces/kits/js/medialibrary/BUILD.gn b/interfaces/kits/js/medialibrary/BUILD.gn new file mode 100644 index 0000000000..62227cdd4f --- /dev/null +++ b/interfaces/kits/js/medialibrary/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +js_declaration("medialibrary_js") { + part_name = "multimedia_media_library_standard" + sources = [ "./@ohos.multimedia.medialibrary.d.ts" ] +} + +ohos_copy("medialibrary_declaration") { + sources = [ "./@ohos.multimedia.medialibrary.d.ts" ] + outputs = [ target_out_dir + "/$target_name/" ] + module_source_dir = target_out_dir + "/$target_name" + module_install_name = "" +} + +ohos_shared_library("medialibrary") { + include_dirs = [ + "//foundation/multimedia/medialibrary_standard/interfaces/kits/js/medialibrary/include", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//foundation/multimedia/medialibrary_standard/interfaces/innerkits/native/include", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_proxy/include", + ] + + sources = [ + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/album_asset_napi.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/audio_asset_napi.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/image_asset_napi.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/media_asset_napi.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/media_library_napi.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/native_module_ohos_medialibrary.cpp", + "//foundation/multimedia/medialibrary_standard/frameworks/kitsimpl/medialibrary/src/video_asset_napi.cpp", + ] + + deps = [ + "//foundation/ace/napi:ace_napi", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/media_library:media_library", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_proxy:medialibrary_proxy", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + relative_install_dir = "module/multimedia" + subsystem_name = "multimedia" + part_name = "multimedia_media_library_standard" +} diff --git a/interfaces/kits/js/medialibrary/include/album_asset_napi.h b/interfaces/kits/js/medialibrary/include/album_asset_napi.h new file mode 100644 index 0000000000..b33231e682 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/album_asset_napi.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ALBUM_ASSET_NAPI_H +#define ALBUM_ASSET_NAPI_H + +#include "album_asset.h" +#include "video_asset_napi.h" +#include "image_asset_napi.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include +#include + +namespace OHOS { +static const std::string ALBUM_ASSET_NAPI_CLASS_NAME = "Album"; + +class AlbumAssetNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value CreateAlbumAsset(napi_env env, AlbumType type, + Media::AlbumAsset &aAsset, + Media::IMediaLibraryClient &mediaLibClient); + Media::IMediaLibraryClient* GetMediaLibClientInstance(); + + AlbumAssetNapi(); + ~AlbumAssetNapi(); + +private: + static void AlbumAssetNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value AlbumAssetNapiConstructor(napi_env env, napi_callback_info info); + + static napi_value GetAlbumId(napi_env env, napi_callback_info info); + static napi_value GetAlbumName(napi_env env, napi_callback_info info); + static napi_value JSSetAlbumName(napi_env env, napi_callback_info info); + static napi_value GetVideoAssets(napi_env env, napi_callback_info info); + static napi_value GetImageAssets(napi_env env, napi_callback_info info); + + static napi_value CommitCreate(napi_env env, napi_callback_info info); + static napi_value CommitDelete(napi_env env, napi_callback_info info); + static napi_value CommitModify(napi_env env, napi_callback_info info); + + void UpdateAlbumAssetInfo(); + + int32_t albumId_; + std::string albumName_; + std::vector> videoAssets_; + std::vector> imageAssets_; + std::string newAlbumName_ = ""; + AlbumType type_; + std::string albumPath_ = ""; + Media::IMediaLibraryClient *mediaLibrary_; + + napi_env env_; + napi_ref wrapper_; + + static napi_ref sConstructor_; + static Media::AlbumAsset *sAlbumAsset_; + static AlbumType sAlbumType_; + static Media::IMediaLibraryClient *sMediaLibrary_; +}; + +struct AlbumAsyncContext { + napi_env env; + napi_async_work work; + napi_deferred deferred; + napi_ref callbackRef; + AlbumAssetNapi* objectInfo; + bool status; + std::vector> videoAssets; + std::vector> imageAssets; +}; +} // namespace OHOS +#endif /* ALBUM_ASSET_NAPI_H */ diff --git a/interfaces/kits/js/medialibrary/include/audio_asset_napi.h b/interfaces/kits/js/medialibrary/include/audio_asset_napi.h new file mode 100644 index 0000000000..2d555c41dc --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/audio_asset_napi.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_ASSET_NAPI_H +#define AUDIO_ASSET_NAPI_H + +#include "audio_asset.h" +#include "media_asset_napi.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +static const std::string AUDIO_ASSET_NAPI_CLASS_NAME = "AudioAsset"; + +class AudioAssetNapi : public MediaAssetNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value CreateAudioAsset(napi_env env, Media::AudioAsset &aAsset, + Media::IMediaLibraryClient &mediaLibClient); + + AudioAssetNapi(); + ~AudioAssetNapi(); + +private: + static void AudioAssetNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value AudioAssetNapiConstructor(napi_env env, napi_callback_info info); + + static napi_value GetMimeType(napi_env env, napi_callback_info info); + static napi_value GetTitle(napi_env env, napi_callback_info info); + static napi_value GetArtist(napi_env env, napi_callback_info info); + static napi_value GetDuration(napi_env env, napi_callback_info info); + + void UpdateAudioAssetInfo(); + + std::string mimeType_; + std::string title_; + std::string artist_; + int32_t duration_; + + napi_env env_; + napi_ref wrapper_; + + static napi_ref sConstructor_; + static Media::AudioAsset *sAudioAsset_; + static Media::IMediaLibraryClient *sMediaLibrary_; +}; +} // namespace OHOS +#endif /* AUDIO_ASSET_NAPI_H */ diff --git a/interfaces/kits/js/medialibrary/include/image_asset_napi.h b/interfaces/kits/js/medialibrary/include/image_asset_napi.h new file mode 100644 index 0000000000..df074b8f69 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/image_asset_napi.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMAGE_ASSET_NAPI_H +#define IMAGE_ASSET_NAPI_H + +#include "image_asset.h" +#include "media_asset_napi.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +static const std::string IMAGE_ASSET_NAPI_CLASS_NAME = "ImageAsset"; + +class ImageAssetNapi : public MediaAssetNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value CreateImageAsset(napi_env env, Media::ImageAsset &iAsset, + Media::IMediaLibraryClient &mediaLibClient); + + ImageAssetNapi(); + ~ImageAssetNapi(); + +private: + static void ImageAssetNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value ImageAssetNapiConstructor(napi_env env, napi_callback_info info); + + static napi_value GetMimeType(napi_env env, napi_callback_info info); + static napi_value GetWidth(napi_env env, napi_callback_info info); + static napi_value GetHeight(napi_env env, napi_callback_info info); + + void UpdateImageAssetInfo(); + + std::string mimeType_; + int32_t width_; + int32_t height_; + + napi_env env_; + napi_ref wrapper_; + + static napi_ref sConstructor_; + static Media::ImageAsset *sImageAsset_; + static Media::IMediaLibraryClient *sMediaLibrary_; +}; +} // namespace OHOS +#endif /* IMAGE_ASSET_NAPI_H */ diff --git a/interfaces/kits/js/medialibrary/include/media_asset_napi.h b/interfaces/kits/js/medialibrary/include/media_asset_napi.h new file mode 100644 index 0000000000..f563fbe9ad --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/media_asset_napi.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_ASSET_NAPI_H +#define MEDIA_ASSET_NAPI_H + +#include "media_asset.h" +#include "IMediaLibraryClient.h" +#include "medialibrary_napi_utils.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +static const std::string MEDIA_ASSET_NAPI_CLASS_NAME = "MediaAsset"; + +class MediaAssetNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value CreateMediaAsset(napi_env env, Media::MediaAsset &mAsset, + Media::IMediaLibraryClient &mediaLibClient); + + MediaAssetNapi(); + virtual ~MediaAssetNapi(); + + static napi_value GetId(napi_env env, napi_callback_info info); + static napi_value GetUri(napi_env env, napi_callback_info info); + static napi_value GetMediaType(napi_env env, napi_callback_info info); + static napi_value GetName(napi_env env, napi_callback_info info); + static napi_value GetSize(napi_env env, napi_callback_info info); + static napi_value GetDateAdded(napi_env env, napi_callback_info info); + static napi_value GetDateModified(napi_env env, napi_callback_info info); + static napi_value GetAlbumName(napi_env env, napi_callback_info info); + static napi_value GetAlbumId(napi_env env, napi_callback_info info); + + static napi_value StartCreate(napi_env env, napi_callback_info info); + static napi_value StartModify(napi_env env, napi_callback_info info); + + static napi_value CancelCreate(napi_env env, napi_callback_info info); + static napi_value CancelModify(napi_env env, napi_callback_info info); + + static napi_value CommitCreate(napi_env env, napi_callback_info info); + static napi_value CommitModify(napi_env env, napi_callback_info info); + static napi_value CommitDelete(napi_env env, napi_callback_info info); + static napi_value CommitCopy(napi_env env, napi_callback_info info); + + static napi_value JSSetName(napi_env env, napi_callback_info info); + static napi_value JSSetAlbumName(napi_env env, napi_callback_info info); + + void UpdateNativeMediaAsset(Media::MediaAsset& mAsset); + + void SetId(int32_t id); + void SetUri(std::string uri); + void SetMediaType(int32_t mediaType); + void SetName(std::string name); + void SetSize(uint64_t size); + void SetDateAdded(uint64_t dateAdded); + void SetDateModified(uint64_t dateModified); + void SetAlbumName(std::string albumName); + void SetAlbumId(int32_t albumId); + void SetMediaLibraryClient(Media::IMediaLibraryClient &mediaLibrary); + +private: + static void MediaAssetNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value MediaAssetNapiConstructor(napi_env env, napi_callback_info info); + + void UpdateMediaAssetInfo(Media::MediaAsset &mediaAsset); + + napi_env env_; + napi_ref wrapper_; + + int32_t id_; + std::string uri_; + int32_t mediaType_; + std::string name_; + uint64_t size_; + uint64_t dateAdded_; + uint64_t dateModified_; + std::string albumName_; + int32_t albumId_; + Media::IMediaLibraryClient *mediaLibrary_; + + std::string newName_ = ""; + std::string newAlbumName_ = ""; + bool startCreateFlag = false; + bool startModifyFlag = false; + + static napi_ref sConstructor_; + static Media::MediaAsset *sMediaAsset_; + static Media::IMediaLibraryClient *sMediaLibrary_; +}; + +struct MediaAssetAsyncContext { + napi_env env; + napi_async_work work; + napi_deferred deferred; + napi_ref callbackRef; + MediaAssetNapi* objectInfo; + MediaAssetNapi* targetCopyObject; + bool status; +}; +} // namespace OHOS +#endif /* MEDIA_ASSET_NAPI_H */ diff --git a/interfaces/kits/js/medialibrary/include/media_library_napi.h b/interfaces/kits/js/medialibrary/include/media_library_napi.h new file mode 100644 index 0000000000..4c8e1939f1 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/media_library_napi.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_LIBRARY_NAPI_H +#define MEDIA_LIBRARY_NAPI_H + +#include "IMediaLibraryClient.h" + +#include "media_asset_napi.h" +#include "audio_asset_napi.h" +#include "video_asset_napi.h" +#include "image_asset_napi.h" +#include "album_asset_napi.h" + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +static const std::string MEDIA_LIBRARY_NAPI_CLASS_NAME = "MediaLibraryHelper"; + +class MediaLibraryNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + Media::IMediaLibraryClient* GetMediaLibClientInstance(); + + MediaLibraryNapi(); + ~MediaLibraryNapi(); + +private: + static void MediaLibraryNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value MediaLibraryNapiConstructor(napi_env env, napi_callback_info info); + + static napi_value GetMediaLibraryInstance(napi_env env, napi_callback_info info); + static napi_value GetMediaAssets(napi_env env, napi_callback_info info); + static napi_value GetAudioAssets(napi_env env, napi_callback_info info); + static napi_value GetVideoAssets(napi_env env, napi_callback_info info); + static napi_value GetImageAssets(napi_env env, napi_callback_info info); + static napi_value GetVideoAlbums(napi_env env, napi_callback_info info); + static napi_value GetImageAlbums(napi_env env, napi_callback_info info); + static napi_value CreateAudioAsset(napi_env env, napi_callback_info info); + static napi_value CreateVideoAsset(napi_env env, napi_callback_info info); + static napi_value CreateImageAsset(napi_env env, napi_callback_info info); + static napi_value CreateAlbum(napi_env env, napi_callback_info info); + + Media::IMediaLibraryClient *mediaLibrary_; + + napi_env env_; + napi_ref wrapper_; + + static napi_ref sConstructor_; +}; + +struct MediaLibraryAsyncContext { + napi_env env; + napi_async_work work; + napi_deferred deferred; + napi_ref callbackRef; + int status; + AssetType assetType; + AlbumType albumType; + MediaLibraryNapi* objectInfo; + std::string selection; + std::vector selectionArgs; + std::vector> mediaAssets; + std::vector> audioAssets; + std::vector> videoAssets; + std::vector> imageAssets; + std::vector> albumAssets; +}; +} // namespace OHOS +#endif /* MEDIA_LIBRARY_NAPI_H */ diff --git a/interfaces/kits/js/medialibrary/include/medialibrary_napi_utils.h b/interfaces/kits/js/medialibrary/include/medialibrary_napi_utils.h new file mode 100644 index 0000000000..42841c7b43 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/medialibrary_napi_utils.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIALIBRARY_NAPI_UTILS_H +#define MEDIALIBRARY_NAPI_UTILS_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#define GET_JS_ARGS(env, info, num) \ + size_t argc = num; \ + napi_value argv[num] = {0}; \ + napi_value thisVar = nullptr; \ + void* data; \ + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) + +#define GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status) \ + napi_value thisVar = nullptr; \ + void* data; \ + status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data) + +#define GET_JS_ASYNC_CB_REF(env, arg, count, cbRef) \ + napi_valuetype valueType = napi_undefined; \ + napi_typeof(env, arg, &valueType); \ + if (valueType == napi_function) { \ + napi_create_reference(env, arg, count, &cbRef); \ + } else { \ + NAPI_ASSERT(env, false, "type mismatch"); \ + } + +#define ASSERT_NULLPTR_CHECK(env, result) \ + if (result == nullptr) { \ + napi_get_undefined(env, &result); \ + return result; \ + } + +#define NAPI_CREATE_PROMISE(env, callbackRef, deferred, result) \ + if (callbackRef == nullptr) { \ + napi_create_promise(env, &deferred, &result); \ + } + +#define NAPI_CREATE_RESOURCE_NAME(env, resourceName) \ + napi_value resource = nullptr; \ + napi_create_string_utf8(env, resourceName, NAPI_AUTO_LENGTH, &resource); + +/* Constants for array index */ +const int PARAM0 = 0; +const int PARAM1 = 1; + +/* Constants for array size */ +const int ARGS_ONE = 1; +const int ARGS_TWO = 2; +const int SIZE = 100; + +namespace OHOS { +enum AssetType { + TYPE_AUDIO = 0, + TYPE_VIDEO = 1, + TYPE_IMAGE = 2, + TYPE_ALBUM = 3, +}; + +enum AlbumType { + TYPE_VIDEO_ALBUM = 0, + TYPE_IMAGE_ALBUM = 1, + TYPE_NONE = 2, +}; + +/* Util class used by napi asynchronous methods for making call to js callback function */ +class MediaLibraryNapiUtils { +public: + static void InvokeJSAsyncMethod(napi_env env, napi_deferred deferred, napi_value result[], + size_t argc, napi_ref callbackRef, napi_async_work work) + { + napi_value retVal; + napi_value callback = nullptr; + + /* Deferred is used when JS Callback method expects a promise value */ + if (deferred) { + napi_resolve_deferred(env, deferred, result[PARAM1]); + } else { + napi_get_reference_value(env, callbackRef, &callback); + napi_call_function(env, nullptr, callback, argc, result, &retVal); + napi_delete_reference(env, callbackRef); + } + napi_delete_async_work(env, work); + } +}; +} // namespace OHOS +#endif /* MEDIALIBRARY_NAPI_UTILS_H */ diff --git a/interfaces/kits/js/medialibrary/include/native_module_ohos_medialibrary.h b/interfaces/kits/js/medialibrary/include/native_module_ohos_medialibrary.h new file mode 100644 index 0000000000..2d1f87e563 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/native_module_ohos_medialibrary.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NATIVE_MODULE_OHOS_MEDIALIBRARY_H_ +#define NATIVE_MODULE_OHOS_MEDIALIBRARY_H_ + +#include "napi/native_node_api.h" +#include "media_library_napi.h" +#include "media_asset_napi.h" +#include "audio_asset_napi.h" +#include "video_asset_napi.h" +#include "image_asset_napi.h" +#include "album_asset_napi.h" + +#endif /* NATIVE_MODULE_OHOS_MEDIALIBRARY_H_ */ diff --git a/interfaces/kits/js/medialibrary/include/video_asset_napi.h b/interfaces/kits/js/medialibrary/include/video_asset_napi.h new file mode 100644 index 0000000000..8398648d12 --- /dev/null +++ b/interfaces/kits/js/medialibrary/include/video_asset_napi.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIDEO_ASSET_NAPI_H +#define VIDEO_ASSET_NAPI_H + +#include "video_asset.h" +#include "media_asset_napi.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +static const std::string VIDEO_ASSET_NAPI_CLASS_NAME = "VideoAsset"; + +class VideoAssetNapi : public MediaAssetNapi { +public: + static napi_value Init(napi_env env, napi_value exports); + static napi_value CreateVideoAsset(napi_env env, Media::VideoAsset &vAsset, + Media::IMediaLibraryClient &mediaLibClient); + + VideoAssetNapi(); + ~VideoAssetNapi(); + +private: + static void VideoAssetNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint); + static napi_value VideoAssetNapiConstructor(napi_env env, napi_callback_info info); + + static napi_value GetMimeType(napi_env env, napi_callback_info info); + static napi_value GetWidth(napi_env env, napi_callback_info info); + static napi_value GetHeight(napi_env env, napi_callback_info info); + static napi_value GetDuration(napi_env env, napi_callback_info info); + + void UpdateVideoAssetInfo(); + + std::string mimeType_; + int32_t width_; + int32_t height_; + int32_t duration_; + + napi_env env_; + napi_ref wrapper_; + + static napi_ref sConstructor_; + static Media::VideoAsset *sVideoAsset_; + static Media::IMediaLibraryClient *sMediaLibrary_; +}; +} // namespace OHOS +#endif /* VIDEO_ASSET_NAPI_H */ diff --git a/ohos.build b/ohos.build new file mode 100644 index 0000000000..2ed84e0931 --- /dev/null +++ b/ohos.build @@ -0,0 +1,47 @@ +{ + "subsystem": "multimedia", + "parts": { + "multimedia_media_library_standard": { + "variants": [ + "phone" + ], + "module_list": [ + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/media_library:media_library_packages", + "//foundation/multimedia/medialibrary_standard/sa_profile:medialibrary_service_sa_profile", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_proxy:medialibrary_proxy", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_service:medialibrary_service", + "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/prebuilts/etcs:medialibrary_service.rc", + "//foundation/multimedia/medialibrary_standard/interfaces/kits/js/medialibrary:medialibrary", + "//foundation/multimedia/medialibrary_standard/interfaces/kits/js/medialibrary:medialibrary_js" + ], + "inner_kits": [ + { + "type": "none", + "name": "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/media_library:media_library_packages", + "header": { + "header_files": [ + "album_asset.h", + "audio_asset.h", + "image_asset.h", + "media_asset.h", + "media_library.h", + "media_log.h", + "video_asset.h" + ], + "header_base": "//foundation/multimedia/medialibrary_standard/interfaces/innerkits/native/include" + } + }, + { + "type": "none", + "name": "//foundation/multimedia/medialibrary_standard/frameworks/innerkitsimpl/medialibrary_proxy:medialibrary_proxy", + "header": { + "header_files": [ + "media_library_client.h" + ], + "header_base": "//foundation/multimedia/medialibrary_standard/interfaces/innerkits/native/include" + } + } + ] + } + } +} diff --git a/sa_profile/3007.xml b/sa_profile/3007.xml new file mode 100644 index 0000000000..e93fa92acb --- /dev/null +++ b/sa_profile/3007.xml @@ -0,0 +1,28 @@ + + + + medialibrary_service + + /system/lib/libmedialibrary_service.z.so + + + 3007 + /system/lib/libmedialibrary_service.z.so + true + false + 1 + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 0000000000..2b7275b9e2 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("medialibrary_service_sa_profile") { + sources = [ "3007.xml" ] + + part_name = "multimedia_media_library_standard" +} -- Gitee