已开启
增加相册、设置、桌面系统应用 #166
奥德彪创建于 5月28日
增加相册、设置、桌面系统应用 #166
已开启
共 61 个文件变更+3581-229
| @@ -59,6 +59,7 @@ Note:If the text contains special characters, please escape them according to th | |||
| 59 | <licensefile></licensefile> | 59 | <licensefile></licensefile> |
| 60 | <policylist> | 60 | <policylist> |
| 61 | <policy name="projectPolicy" desc=""> | 61 | <policy name="projectPolicy" desc=""> |
| 62 | + <policyitem type="copyright" name="Copyright (c) 2026 RKH Corp." path=".*" desc="copyright"/> | ||
| 62 | </policy> | 63 | </policy> |
| 63 | </policylist> | 64 | </policylist> |
| 64 | <filefilterlist> | 65 | <filefilterlist> |
| @@ -30,6 +30,7 @@ | |||
| 30 | "syspara_lite", | 30 | "syspara_lite", |
| 31 | "camera_lite", | 31 | "camera_lite", |
| 32 | "media_lite", | 32 | "media_lite", |
| 33 | + "audio_lite", | ||
| 33 | "permission", | 34 | "permission", |
| 34 | "samgr_lite", | 35 | "samgr_lite", |
| 35 | "utils_base" | 36 | "utils_base" |
| @@ -45,10 +46,12 @@ | |||
| 45 | "//applications/sample/camera/cameraApp:cameraApp_hap", | 46 | "//applications/sample/camera/cameraApp:cameraApp_hap", |
| 46 | "//applications/sample/camera/setting:setting_hap", | 47 | "//applications/sample/camera/setting:setting_hap", |
| 47 | "//applications/sample/camera/gallery:gallery_hap", | 48 | "//applications/sample/camera/gallery:gallery_hap", |
| 49 | + "//applications/sample/camera/recorder:recorder_hap", | ||
| 50 | + "//applications/sample/camera/gallery:test_jpeg", | ||
| 48 | "//applications/sample/camera/media:media_sample" | 51 | "//applications/sample/camera/media:media_sample" |
| 49 | ], | 52 | ], |
| 50 | "inner_kits": [], | 53 | "inner_kits": [], |
| 51 | "test": [] | 54 | "test": [] |
| 52 | } | 55 | } |
| 53 | } | 56 | } |
| 54 | -} | 57 | +} |
| @@ -13,12 +13,22 @@ | |||
| 13 | 13 | ||
| 14 | import("//build/lite/config/hap_pack.gni") | 14 | import("//build/lite/config/hap_pack.gni") |
| 15 | 15 | ||
| 16 | +config("hilog_dir") { | ||
| 17 | + include_dirs = | ||
| 18 | + [ "//base/hiviewdfx/hilog_lite/interfaces/native/innerkits/hilog/" ] | ||
| 19 | +} | ||
| 20 | +config("hilog_lite_dir") { | ||
| 21 | + include_dirs = | ||
| 22 | + [ "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite/" ] | ||
| 23 | +} | ||
| 24 | + | ||
| 16 | shared_library("gallery") { | 25 | shared_library("gallery") { |
| 17 | sources = [ | 26 | sources = [ |
| 18 | "src/gallery_ability.cpp", | 27 | "src/gallery_ability.cpp", |
| 19 | "src/gallery_ability_slice.cpp", | 28 | "src/gallery_ability_slice.cpp", |
| 20 | "src/picture_ability_slice.cpp", | 29 | "src/picture_ability_slice.cpp", |
| 21 | "src/player_ability_slice.cpp", | 30 | "src/player_ability_slice.cpp", |
| 31 | + "src/image_decoder.cpp", | ||
| 22 | ] | 32 | ] |
| 23 | 33 | ||
| 24 | include_dirs = [ | 34 | include_dirs = [ |
| @@ -27,6 +37,7 @@ shared_library("gallery") { | |||
| 27 | "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", | 37 | "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", |
| 28 | "${aafwk_lite_path}/interfaces/kits/want_lite", | 38 | "${aafwk_lite_path}/interfaces/kits/want_lite", |
| 29 | "//foundation/multimedia/media_lite/interfaces/kits/player_lite", | 39 | "//foundation/multimedia/media_lite/interfaces/kits/player_lite", |
| 40 | + "//foundation/arkui/ui_lite/frameworks", | ||
| 30 | ] | 41 | ] |
| 31 | 42 | ||
| 32 | deps = [ | 43 | deps = [ |
| @@ -41,6 +52,19 @@ shared_library("gallery") { | |||
| 41 | "//foundation/systemabilitymgr/samgr_lite/samgr:samgr", | 52 | "//foundation/systemabilitymgr/samgr_lite/samgr:samgr", |
| 42 | ] | 53 | ] |
| 43 | 54 | ||
| 55 | + if (defined(ohos_lite)) { | ||
| 56 | + if (ohos_kernel_type == "liteos_m") { | ||
| 57 | + configs += [ ":hilog_lite_dir" ] | ||
| 58 | + deps += [ "//base/hiviewdfx/hilog_lite/frameworks/mini:hilog_lite" ] | ||
| 59 | + } else if (ohos_kernel_type == "liteos_a") { | ||
| 60 | + configs += [ ":hilog_dir" ] | ||
| 61 | + deps += [ | ||
| 62 | + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", | ||
| 63 | + "//third_party/bounds_checking_function:libsec_shared", | ||
| 64 | + ] | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 44 | ldflags = [ "-shared" ] | 68 | ldflags = [ "-shared" ] |
| 45 | 69 | ||
| 46 | ldflags += [ "-lstdc++" ] | 70 | ldflags += [ "-lstdc++" ] |
| @@ -58,7 +82,26 @@ shared_library("gallery") { | |||
| 58 | "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER", | 82 | "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER", |
| 59 | "ENABLE_WINDOW=1", | 83 | "ENABLE_WINDOW=1", |
| 60 | "ABILITY_WINDOW_SUPPORT", | 84 | "ABILITY_WINDOW_SUPPORT", |
| 85 | + "HILOG_ENABLE", | ||
| 61 | ] | 86 | ] |
| 87 | + | ||
| 88 | + # image decode for jpeg/png | ||
| 89 | + deps += [ | ||
| 90 | + "//third_party/libjpeg-turbo:libjpeg", | ||
| 91 | + "//third_party/libpng:libpng", | ||
| 92 | + ] | ||
| 93 | + defines += [ | ||
| 94 | + "ENABLE_JPEG = 1", | ||
| 95 | + "ENABLE_PNG = 1", | ||
| 96 | + ] | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +copy("test_jpeg") { | ||
| 100 | + sources = [ | ||
| 101 | + "resources/photos/photo1.jpeg", | ||
| 102 | + "resources/photos/photo2.jpeg" | ||
| 103 | + ] | ||
| 104 | + outputs = [ "${root_out_dir}/system/internal/{{source_file_part}}" ] | ||
| 62 | } | 105 | } |
| 63 | 106 | ||
| 64 | hap_pack("gallery_hap") { | 107 | hap_pack("gallery_hap") { |
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <components/ui_scroll_view.h> | 22 | #include <components/ui_scroll_view.h> |
| 23 | #include "event_listener.h" | 23 | #include "event_listener.h" |
| 24 | #include "gallery_config.h" | 24 | #include "gallery_config.h" |
| 25 | +#include "image_decoder.h" | ||
| 25 | 26 | ||
| 26 | namespace OHOS { | 27 | namespace OHOS { |
| 27 | class GalleryAbilitySlice : public AbilitySlice { | 28 | class GalleryAbilitySlice : public AbilitySlice { |
| @@ -63,6 +64,7 @@ private: | |||
| 63 | char videoTagIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | 64 | char videoTagIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; |
| 64 | uint16_t pictureOnClickListenerCount_ { 0 }; | 65 | uint16_t pictureOnClickListenerCount_ { 0 }; |
| 65 | EventListener* pictureOnClickListener_[MAX_PICTURE_COUNT] = { nullptr }; | 66 | EventListener* pictureOnClickListener_[MAX_PICTURE_COUNT] = { nullptr }; |
| 67 | + ImageDecoder* imageDecoder_ { nullptr }; | ||
| 66 | }; | 68 | }; |
| 67 | } | 69 | } |
| 68 | #endif // OHOS_GALLERY_ABILITY_SLICE_H | 70 | #endif // OHOS_GALLERY_ABILITY_SLICE_H |
| @@ -16,7 +16,11 @@ | |||
| 16 | #ifndef OHOS_GALLERY_CONFIG_H | 16 | #ifndef OHOS_GALLERY_CONFIG_H |
| 17 | #define OHOS_GALLERY_CONFIG_H | 17 | #define OHOS_GALLERY_CONFIG_H |
| 18 | 18 | ||
| 19 | +#include "components/ui_view_group.h" | ||
| 20 | +#define GALLERY_BACKGROUND_COLOR Color::ColorTo32(Color::GetColorFromRGB(0xdd, 0xdd, 0xdd)) | ||
| 21 | + | ||
| 19 | namespace OHOS { | 22 | namespace OHOS { |
| 23 | + | ||
| 20 | /** icon resource file path */ | 24 | /** icon resource file path */ |
| 21 | static const char* const BACK_ICON_PATH = "/gallery/assets/gallery/resources/drawable/ic_back.png"; | 25 | static const char* const BACK_ICON_PATH = "/gallery/assets/gallery/resources/drawable/ic_back.png"; |
| 22 | static const char* const VIDEO_TAG_ICON_PATH = "/gallery/assets/gallery/resources/drawable/ic_gallery_video_tag.png"; | 26 | static const char* const VIDEO_TAG_ICON_PATH = "/gallery/assets/gallery/resources/drawable/ic_gallery_video_tag.png"; |
| @@ -29,13 +33,13 @@ static constexpr uint16_t MAX_PATH_LENGTH = 512; | |||
| 29 | /** thumb, photo, and video folder path */ | 33 | /** thumb, photo, and video folder path */ |
| 30 | static const char* const THUMBNAIL_DIRECTORY = "/userdata/thumb"; | 34 | static const char* const THUMBNAIL_DIRECTORY = "/userdata/thumb"; |
| 31 | static const char* const PHOTO_DIRECTORY = "/userdata/photo"; | 35 | static const char* const PHOTO_DIRECTORY = "/userdata/photo"; |
| 32 | -static const char* const VIDEO_SOURCE_DIRECTORY = "/userdata/video"; | 36 | +static const char* const VIDEO_SOURCE_DIRECTORY = "/userdata/photo"; |
| 33 | 37 | ||
| 34 | /** general page configuration */ | 38 | /** general page configuration */ |
| 35 | static constexpr int ROOT_VIEW_POSITION_X = 0; | 39 | static constexpr int ROOT_VIEW_POSITION_X = 0; |
| 36 | static constexpr int ROOT_VIEW_POSITION_Y = 0; | 40 | static constexpr int ROOT_VIEW_POSITION_Y = 0; |
| 37 | -static constexpr int ROOT_VIEW_WIDTH = 960; | 41 | +static constexpr int ROOT_VIEW_WIDTH = 1920; |
| 38 | -static constexpr int ROOT_VIEW_HEIGHT = 480; | 42 | +static constexpr int ROOT_VIEW_HEIGHT = 1080; |
| 39 | static constexpr uint16_t ROOT_VIEW_OPACITY = 255; | 43 | static constexpr uint16_t ROOT_VIEW_OPACITY = 255; |
| 40 | 44 | ||
| 41 | static const char* const FONT_NAME = "SourceHanSansSC-Regular.otf"; | 45 | static const char* const FONT_NAME = "SourceHanSansSC-Regular.otf"; |
| @@ -45,18 +49,20 @@ static constexpr int16_t BACK_ICON_POSITION_X = 38; | |||
| 45 | static constexpr int16_t BACK_ICON_POSITION_Y = 17; | 49 | static constexpr int16_t BACK_ICON_POSITION_Y = 17; |
| 46 | 50 | ||
| 47 | /** THUMBNAIL */ | 51 | /** THUMBNAIL */ |
| 48 | -static constexpr int16_t THUMBNAIL_RESOLUTION_X = 120; | 52 | +static constexpr int16_t THUMBNAIL_RESOLUTION_X = 236; |
| 49 | -static constexpr int16_t THUMBNAIL_RESOLUTION_Y = 120; | 53 | +static constexpr int16_t THUMBNAIL_RESOLUTION_Y = 236; |
| 50 | static constexpr int16_t THUMBNAIL_SPACE = 4; | 54 | static constexpr int16_t THUMBNAIL_SPACE = 4; |
| 51 | static constexpr int16_t THUMBNAIL_COLUMN = 3; | 55 | static constexpr int16_t THUMBNAIL_COLUMN = 3; |
| 52 | 56 | ||
| 53 | static constexpr int16_t VIDEO_TAG_POSITION_X = 10; | 57 | static constexpr int16_t VIDEO_TAG_POSITION_X = 10; |
| 54 | static constexpr int16_t VIDEO_TAG_POSITION_Y = THUMBNAIL_RESOLUTION_Y - 37; | 58 | static constexpr int16_t VIDEO_TAG_POSITION_Y = THUMBNAIL_RESOLUTION_Y - 37; |
| 59 | +static constexpr int16_t VIDEO_TAG_WIDTH = 27; | ||
| 60 | +static constexpr int16_t VIDEO_TAG_HEIGHT = 27; | ||
| 55 | 61 | ||
| 56 | /** title */ | 62 | /** title */ |
| 57 | static constexpr int16_t LABEL_POSITION_X = BACK_ICON_POSITION_X + 60; | 63 | static constexpr int16_t LABEL_POSITION_X = BACK_ICON_POSITION_X + 60; |
| 58 | static constexpr int16_t LABEL_POSITION_Y = 0; | 64 | static constexpr int16_t LABEL_POSITION_Y = 0; |
| 59 | -static constexpr int16_t LABEL_WIDTH = 100; | 65 | +static constexpr int16_t LABEL_WIDTH = 200; |
| 60 | static constexpr int16_t LABEL_HEIGHT = 70; | 66 | static constexpr int16_t LABEL_HEIGHT = 70; |
| 61 | static constexpr uint16_t GALLERY_FONT_SIZE = 25; | 67 | static constexpr uint16_t GALLERY_FONT_SIZE = 25; |
| 62 | static constexpr uint16_t GALLERY_DELETE_FONT_SIZE = 22; | 68 | static constexpr uint16_t GALLERY_DELETE_FONT_SIZE = 22; |
| @@ -91,5 +97,6 @@ static constexpr uint16_t SLIDER_WIDTH = ROOT_VIEW_WIDTH - SLIDER_X - TOTAL_TIME | |||
| 91 | static constexpr uint16_t KNOB_WIDTH = 25; | 97 | static constexpr uint16_t KNOB_WIDTH = 25; |
| 92 | 98 | ||
| 93 | static constexpr uint16_t PLAYER_FONT_SIZE = 18; | 99 | static constexpr uint16_t PLAYER_FONT_SIZE = 18; |
| 100 | + | ||
| 94 | } // namespace OHOS | 101 | } // namespace OHOS |
| 95 | #endif // OHOS_GALLERY_CONFIG_H | 102 | #endif // OHOS_GALLERY_CONFIG_H |
| @@ -0,0 +1,70 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef GALLERY_LOG_H | ||
| 17 | +#define GALLERY_LOG_H | ||
| 18 | + | ||
| 19 | +#ifdef HILOG_ENABLE | ||
| 20 | + | ||
| 21 | +#ifndef LOG_DOMAIN | ||
| 22 | +#define LOG_DOMAIN 0xD0000 | ||
| 23 | +#endif | ||
| 24 | + | ||
| 25 | +#ifndef LOG_TAG | ||
| 26 | +#define LOG_TAG "[GALLERY]" | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | +#include <hilog/log.h> | ||
| 30 | + | ||
| 31 | +#ifdef __cplusplus | ||
| 32 | +extern "C" { | ||
| 33 | +#endif | ||
| 34 | + | ||
| 35 | +#define FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__)) | ||
| 36 | + | ||
| 37 | +#define LOGD(fmt, ...) HILOG_DEBUG(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 38 | +#define LOGI(fmt, ...) HILOG_INFO(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 39 | +#define LOGW(fmt, ...) HILOG_WARN(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 40 | +#define LOGE(fmt, ...) HILOG_ERROR(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 41 | +#define LOGF(fmt, ...) HILOG_FATAL(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 42 | + | ||
| 43 | +#ifdef __cplusplus | ||
| 44 | +} | ||
| 45 | +#endif | ||
| 46 | + | ||
| 47 | +#else | ||
| 48 | + | ||
| 49 | +#include <stdio.h> | ||
| 50 | +#include <string.h> | ||
| 51 | + | ||
| 52 | +#ifdef __cplusplus | ||
| 53 | +extern "C" { | ||
| 54 | +#endif | ||
| 55 | + | ||
| 56 | +#define FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__)) | ||
| 57 | + | ||
| 58 | +#define LOGD(fmt, ...) printf("[D][GALLERY][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 59 | +#define LOGI(fmt, ...) printf("[I][GALLERY][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 60 | +#define LOGW(fmt, ...) printf("[W][GALLERY][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 61 | +#define LOGE(fmt, ...) printf("[E][GALLERY][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 62 | +#define LOGF(fmt, ...) printf("[F][GALLERY][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 63 | + | ||
| 64 | +#ifdef __cplusplus | ||
| 65 | +} | ||
| 66 | +#endif | ||
| 67 | + | ||
| 68 | +#endif | ||
| 69 | + | ||
| 70 | +#endif /* GALLERY_LOG_H */ | ||
| @@ -0,0 +1,71 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef GALLERY_IMAGE_DECODER_H | ||
| 17 | +#define GALLERY_IMAGE_DECODER_H | ||
| 18 | + | ||
| 19 | +#include <memory> | ||
| 20 | +#include <string> | ||
| 21 | +#include <functional> | ||
| 22 | +#include <thread> | ||
| 23 | +#include <vector> | ||
| 24 | +#include <queue> | ||
| 25 | +#include <mutex> | ||
| 26 | +#include <condition_variable> | ||
| 27 | +#include <atomic> | ||
| 28 | + | ||
| 29 | +#include <common/image.h> | ||
| 30 | +#include <ability_event_handler.h> | ||
| 31 | + | ||
| 32 | +namespace OHOS { | ||
| 33 | + | ||
| 34 | +class ImageDecoder { | ||
| 35 | +public: | ||
| 36 | + ImageDecoder(AbilityEventHandler* handler, size_t threadCount = 1); | ||
| 37 | + | ||
| 38 | + ~ImageDecoder(); | ||
| 39 | + | ||
| 40 | + void DecodeImage(const std::string& imagePath, std::function<void(ImageInfo)> uiCallback); | ||
| 41 | + | ||
| 42 | + void Start(); | ||
| 43 | + void Stop(); | ||
| 44 | + bool IsRunning(); | ||
| 45 | + | ||
| 46 | +private: | ||
| 47 | + struct DecodeTask { | ||
| 48 | + std::string imagePath; | ||
| 49 | + std::function<void(ImageInfo)> callback; | ||
| 50 | + }; | ||
| 51 | + | ||
| 52 | + void WorkerThread(); | ||
| 53 | + bool TryGetTask(DecodeTask& task); | ||
| 54 | + void HandleTask(const DecodeTask& task); | ||
| 55 | + void NotifyCallback(const DecodeTask& task, const ImageInfo& imageInfo); | ||
| 56 | + | ||
| 57 | + ImageInfo DoDecode(const std::string& imagePath); | ||
| 58 | + | ||
| 59 | +private: | ||
| 60 | + std::vector<std::thread> workerThreads_; // 工作线程池 | ||
| 61 | + std::queue<DecodeTask> taskQueue_; // 任务队列 | ||
| 62 | + std::mutex queueMutex_; // 队列互斥锁 | ||
| 63 | + std::condition_variable taskCond_; // 任务条件变量 | ||
| 64 | + std::atomic<bool> isRunning_; // 运行状态标记 | ||
| 65 | + int maxThreadCount_; // 最大任务个数 | ||
| 66 | + | ||
| 67 | + AbilityEventHandler *eventHandler_ = nullptr; | ||
| 68 | +}; | ||
| 69 | + | ||
| 70 | +} | ||
| 71 | +#endif // GALLERY_IMAGE_DECODER_H | ||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <ability_loader.h> | 19 | #include <ability_loader.h> |
| 20 | #include "components/ui_image_view.h" | 20 | #include "components/ui_image_view.h" |
| 21 | #include "components/ui_view_group.h" | 21 | #include "components/ui_view_group.h" |
| 22 | +#include "components/ui_label.h" | ||
| 22 | #include "event_listener.h" | 23 | #include "event_listener.h" |
| 23 | #include "gallery_config.h" | 24 | #include "gallery_config.h" |
| 24 | 25 | ||
| @@ -36,12 +37,13 @@ protected: | |||
| 36 | 37 | ||
| 37 | private: | 38 | private: |
| 38 | void Clear(); | 39 | void Clear(); |
| 39 | - void InitTitle(); | 40 | + void InitTitle(const char* imageName); |
| 40 | void InitPicture(const char* path); | 41 | void InitPicture(const char* path); |
| 41 | 42 | ||
| 42 | RootView* rootView_ { nullptr }; | 43 | RootView* rootView_ { nullptr }; |
| 43 | UIViewGroup* backArea_ { nullptr }; | 44 | UIViewGroup* backArea_ { nullptr }; |
| 44 | UIImageView* backIcon_ { nullptr }; | 45 | UIImageView* backIcon_ { nullptr }; |
| 46 | + UILabel* titleLabel_ { nullptr }; | ||
| 45 | EventListener* backIconListener_ { nullptr }; | 47 | EventListener* backIconListener_ { nullptr }; |
| 46 | UIImageView* picture_ { nullptr }; | 48 | UIImageView* picture_ { nullptr }; |
| 47 | char backIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | 49 | char backIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; |
| @@ -122,7 +122,7 @@ private: | |||
| 122 | void Clear(); | 122 | void Clear(); |
| 123 | void ShowErrorTips(); | 123 | void ShowErrorTips(); |
| 124 | void SetUpRootView(); | 124 | void SetUpRootView(); |
| 125 | - void SetUpBackArea(const char* pathHeader); | 125 | + void SetUpBackArea(const char* pathHeader, const char* imageName); |
| 126 | void SetUpVideoPlayer(const Want &want); | 126 | void SetUpVideoPlayer(const Want &want); |
| 127 | bool SetUpSurfaceView(); | 127 | bool SetUpSurfaceView(); |
| 128 | void SetUpProgress(int64_t duration); | 128 | void SetUpProgress(int64_t duration); |
| @@ -137,6 +137,7 @@ private: | |||
| 137 | RootView* rootView_ { nullptr }; | 137 | RootView* rootView_ { nullptr }; |
| 138 | UIViewGroup* backArea_ { nullptr }; | 138 | UIViewGroup* backArea_ { nullptr }; |
| 139 | UIImageView* backIcon_ { nullptr }; | 139 | UIImageView* backIcon_ { nullptr }; |
| 140 | + UILabel* titleLabel_ { nullptr }; | ||
| 140 | UISurfaceView* surfaceView_ { nullptr }; | 141 | UISurfaceView* surfaceView_ { nullptr }; |
| 141 | UIViewGroup* animatorGroup_ { nullptr }; | 142 | UIViewGroup* animatorGroup_ { nullptr }; |
| 142 | UIToggleButton* toggleButton_ { nullptr }; | 143 | UIToggleButton* toggleButton_ { nullptr }; |
| @@ -0,0 +1,20 @@ | |||
| 1 | +# Copyright (c) 2026 RKH Corp. | ||
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 3 | +# you may not use this file except in compliance with the License. | ||
| 4 | +# You may obtain a copy of the License at | ||
| 5 | +# | ||
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 7 | +# | ||
| 8 | +# Unless required by applicable law or agreed to in writing, software | ||
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 11 | +# See the License for the specific language governing permissions and | ||
| 12 | +# limitations under the License. | ||
| 13 | + | ||
| 14 | +copy("test_jpeg") { | ||
| 15 | + sources = [ | ||
| 16 | + "photo1.jpeg", | ||
| 17 | + "photo2.jpeg" | ||
| 18 | + ] | ||
| 19 | + outputs = [ "${root_out_dir}/system/internal/{{source_file_part}}" ] | ||
| 20 | +} | ||
| @@ -14,39 +14,39 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include "gallery_ability.h" | 16 | #include "gallery_ability.h" |
| 17 | +#include "gallery_log.h" | ||
| 17 | 18 | ||
| 18 | namespace OHOS { | 19 | namespace OHOS { |
| 19 | REGISTER_AA(GalleryAbility) | 20 | REGISTER_AA(GalleryAbility) |
| 20 | 21 | ||
| 21 | void GalleryAbility::OnStart(const Want &want) | 22 | void GalleryAbility::OnStart(const Want &want) |
| 22 | { | 23 | { |
| 23 | - printf("GalleryAbility::OnStart\n"); | 24 | + LOGI("GalleryAbility::OnStart"); |
| 24 | SetMainRoute("GalleryAbilitySlice"); | 25 | SetMainRoute("GalleryAbilitySlice"); |
| 25 | - | ||
| 26 | Ability::OnStart(want); | 26 | Ability::OnStart(want); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | void GalleryAbility::OnInactive() | 29 | void GalleryAbility::OnInactive() |
| 30 | { | 30 | { |
| 31 | - printf("GalleryAbility::OnInactive\n"); | 31 | + LOGI("GalleryAbility::OnInactive"); |
| 32 | Ability::OnInactive(); | 32 | Ability::OnInactive(); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void GalleryAbility::OnActive(const Want &want) | 35 | void GalleryAbility::OnActive(const Want &want) |
| 36 | { | 36 | { |
| 37 | - printf("GalleryAbility::OnActive\n"); | 37 | + LOGI("GalleryAbility::OnActive"); |
| 38 | Ability::OnActive(want); | 38 | Ability::OnActive(want); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void GalleryAbility::OnBackground() | 41 | void GalleryAbility::OnBackground() |
| 42 | { | 42 | { |
| 43 | - printf("GalleryAbility::OnBackground\n"); | 43 | + LOGI("GalleryAbility::OnBackground"); |
| 44 | Ability::OnBackground(); | 44 | Ability::OnBackground(); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void GalleryAbility::OnStop() | 47 | void GalleryAbility::OnStop() |
| 48 | { | 48 | { |
| 49 | - printf("GalleryAbility::OnStop\n"); | 49 | + LOGI("GalleryAbility::OnStop"); |
| 50 | Ability::OnStop(); | 50 | Ability::OnStop(); |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| @@ -16,24 +16,29 @@ | |||
| 16 | #include "gallery_ability_slice.h" | 16 | #include "gallery_ability_slice.h" |
| 17 | #include "ability_env.h" | 17 | #include "ability_env.h" |
| 18 | #include "ability_manager.h" | 18 | #include "ability_manager.h" |
| 19 | +#include <ability_event_handler.h> | ||
| 19 | #include "picture_ability_slice.h" | 20 | #include "picture_ability_slice.h" |
| 20 | 21 | ||
| 21 | #include "gfx_utils/file.h" | 22 | #include "gfx_utils/file.h" |
| 23 | +#include "gfx_utils/mem_api.h" | ||
| 22 | #include "securec.h" | 24 | #include "securec.h" |
| 23 | 25 | ||
| 26 | +#include "gallery_log.h" | ||
| 27 | +#include "image_decoder.h" | ||
| 28 | + | ||
| 24 | namespace OHOS { | 29 | namespace OHOS { |
| 25 | REGISTER_AS(GalleryAbilitySlice) | 30 | REGISTER_AS(GalleryAbilitySlice) |
| 26 | 31 | ||
| 27 | GalleryAbilitySlice::~GalleryAbilitySlice() | 32 | GalleryAbilitySlice::~GalleryAbilitySlice() |
| 28 | { | 33 | { |
| 29 | - printf("~GalleryAbilitySlice() | start \n"); | 34 | + LOGI("~GalleryAbilitySlice() | start"); |
| 30 | Clear(); | 35 | Clear(); |
| 31 | - printf("~GalleryAbilitySlice() | end \n"); | 36 | + LOGI("~GalleryAbilitySlice() | end"); |
| 32 | } | 37 | } |
| 33 | 38 | ||
| 34 | void GalleryAbilitySlice::Clear() | 39 | void GalleryAbilitySlice::Clear() |
| 35 | { | 40 | { |
| 36 | - printf("GalleryAbilitySlice::Clear() | start \n"); | 41 | + LOGI("GalleryAbilitySlice::Clear() | start"); |
| 37 | if (backIcon_ != nullptr) { | 42 | if (backIcon_ != nullptr) { |
| 38 | delete backIcon_; | 43 | delete backIcon_; |
| 39 | backIcon_ = nullptr; | 44 | backIcon_ = nullptr; |
| @@ -58,6 +63,10 @@ void GalleryAbilitySlice::Clear() | |||
| 58 | delete deleteLabel_; | 63 | delete deleteLabel_; |
| 59 | deleteLabel_ = nullptr; | 64 | deleteLabel_ = nullptr; |
| 60 | } | 65 | } |
| 66 | + if (imageDecoder_ != nullptr) { | ||
| 67 | + delete imageDecoder_; | ||
| 68 | + imageDecoder_ = nullptr; | ||
| 69 | + } | ||
| 61 | 70 | ||
| 62 | ClearThumb(); | 71 | ClearThumb(); |
| 63 | 72 | ||
| @@ -65,12 +74,12 @@ void GalleryAbilitySlice::Clear() | |||
| 65 | RootView::DestroyWindowRootView(rootView_); | 74 | RootView::DestroyWindowRootView(rootView_); |
| 66 | rootView_ = nullptr; | 75 | rootView_ = nullptr; |
| 67 | } | 76 | } |
| 68 | - printf("GalleryAbilitySlice::Clear() | end \n"); | 77 | + LOGI("GalleryAbilitySlice::Clear() | end"); |
| 69 | } | 78 | } |
| 70 | 79 | ||
| 71 | void GalleryAbilitySlice::ClearThumb() | 80 | void GalleryAbilitySlice::ClearThumb() |
| 72 | { | 81 | { |
| 73 | - printf("GalleryAbilitySlice::ClearThumb() | start \n"); | 82 | + LOGI("GalleryAbilitySlice::ClearThumb() | start"); |
| 74 | if (picContainer_ != nullptr) { | 83 | if (picContainer_ != nullptr) { |
| 75 | delete picContainer_; | 84 | delete picContainer_; |
| 76 | picContainer_ = nullptr; | 85 | picContainer_ = nullptr; |
| @@ -94,12 +103,12 @@ void GalleryAbilitySlice::ClearThumb() | |||
| 94 | } | 103 | } |
| 95 | pictureCount_ = 0; | 104 | pictureCount_ = 0; |
| 96 | pictureOnClickListenerCount_ = 0; | 105 | pictureOnClickListenerCount_ = 0; |
| 97 | - printf("GalleryAbilitySlice::ClearThumb() | end \n"); | 106 | + LOGI("GalleryAbilitySlice::ClearThumb() | end"); |
| 98 | } | 107 | } |
| 99 | 108 | ||
| 100 | void GalleryAbilitySlice::ClearPictureList(const UIView* view) | 109 | void GalleryAbilitySlice::ClearPictureList(const UIView* view) |
| 101 | { | 110 | { |
| 102 | - printf("GalleryAbilitySlice::ClearPictureList() | start \n"); | 111 | + LOGI("GalleryAbilitySlice::ClearPictureList() | start"); |
| 103 | if (view == nullptr || !(view->IsViewGroup())) { | 112 | if (view == nullptr || !(view->IsViewGroup())) { |
| 104 | return; | 113 | return; |
| 105 | } | 114 | } |
| @@ -113,12 +122,12 @@ void GalleryAbilitySlice::ClearPictureList(const UIView* view) | |||
| 113 | delete child; | 122 | delete child; |
| 114 | child = childNext; | 123 | child = childNext; |
| 115 | } | 124 | } |
| 116 | - printf("GalleryAbilitySlice::ClearPictureList() | end \n"); | 125 | + LOGI("GalleryAbilitySlice::ClearPictureList() | end"); |
| 117 | } | 126 | } |
| 118 | 127 | ||
| 119 | void GalleryAbilitySlice::InitTitle() | 128 | void GalleryAbilitySlice::InitTitle() |
| 120 | { | 129 | { |
| 121 | - printf("GalleryAbilitySlice::InitTitle | start \n"); | 130 | + LOGI("GalleryAbilitySlice::InitTitle | start"); |
| 122 | backIcon_ = new UIImageView(); | 131 | backIcon_ = new UIImageView(); |
| 123 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); | 132 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); |
| 124 | backIcon_->SetSrc(backIconAbsolutePath); | 133 | backIcon_->SetSrc(backIconAbsolutePath); |
| @@ -130,9 +139,9 @@ void GalleryAbilitySlice::InitTitle() | |||
| 130 | backArea_->SetTouchable(true); | 139 | backArea_->SetTouchable(true); |
| 131 | 140 | ||
| 132 | auto onClick = [this] (UIView& view, const Event& event) -> bool { | 141 | auto onClick = [this] (UIView& view, const Event& event) -> bool { |
| 133 | - printf("############ Next AS enter #############\n"); | 142 | + LOGI("############ Next AS enter #############"); |
| 134 | TerminateAbility(); | 143 | TerminateAbility(); |
| 135 | - printf("############ Next AS exit #############\n"); | 144 | + LOGI("############ Next AS exit #############"); |
| 136 | return true; | 145 | return true; |
| 137 | }; | 146 | }; |
| 138 | backIconListener_ = new EventListener(onClick, nullptr); | 147 | backIconListener_ = new EventListener(onClick, nullptr); |
| @@ -143,6 +152,8 @@ void GalleryAbilitySlice::InitTitle() | |||
| 143 | titleLabel_->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_WIDTH, LABEL_HEIGHT); | 152 | titleLabel_->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_WIDTH, LABEL_HEIGHT); |
| 144 | titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | 153 | titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); |
| 145 | titleLabel_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); | 154 | titleLabel_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); |
| 155 | + titleLabel_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); | ||
| 156 | + titleLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 146 | titleLabel_->SetText("照片"); | 157 | titleLabel_->SetText("照片"); |
| 147 | 158 | ||
| 148 | deleteLabel_ = new UILabel(); | 159 | deleteLabel_ = new UILabel(); |
| @@ -151,12 +162,14 @@ void GalleryAbilitySlice::InitTitle() | |||
| 151 | deleteLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, | 162 | deleteLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, |
| 152 | UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | 163 | UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); |
| 153 | deleteLabel_->SetFont(FONT_NAME, GALLERY_DELETE_FONT_SIZE); | 164 | deleteLabel_->SetFont(FONT_NAME, GALLERY_DELETE_FONT_SIZE); |
| 165 | + deleteLabel_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); | ||
| 166 | + deleteLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 154 | deleteLabel_->SetText("全部删除"); | 167 | deleteLabel_->SetText("全部删除"); |
| 155 | deleteLabel_->SetTouchable(true); | 168 | deleteLabel_->SetTouchable(true); |
| 156 | auto deleteClick = [this] (UIView& view, const Event& event) -> bool { | 169 | auto deleteClick = [this] (UIView& view, const Event& event) -> bool { |
| 157 | - printf("############ DeleteAllData click enter #############\n"); | 170 | + LOGI("############ DeleteAllData click enter #############"); |
| 158 | DeleteAllData(); | 171 | DeleteAllData(); |
| 159 | - printf("############ DeleteAllData click exit #############\n"); | 172 | + LOGI("############ DeleteAllData click exit #############"); |
| 160 | return true; | 173 | return true; |
| 161 | }; | 174 | }; |
| 162 | deleteClickListener_ = new EventListener(deleteClick, nullptr); | 175 | deleteClickListener_ = new EventListener(deleteClick, nullptr); |
| @@ -170,11 +183,12 @@ void GalleryAbilitySlice::InitTitle() | |||
| 170 | 183 | ||
| 171 | void GalleryAbilitySlice::InitPictureList() | 184 | void GalleryAbilitySlice::InitPictureList() |
| 172 | { | 185 | { |
| 173 | - printf("GalleryAbilitySlice::InitPictureList | start \n"); | 186 | + LOGI("GalleryAbilitySlice::InitPictureList | start"); |
| 174 | picContainer_ = new UIScrollView(); | 187 | picContainer_ = new UIScrollView(); |
| 175 | picContainer_->SetPosition(0, LABEL_POSITION_Y + LABEL_HEIGHT); | 188 | picContainer_->SetPosition(0, LABEL_POSITION_Y + LABEL_HEIGHT); |
| 176 | - picContainer_->Resize(ROOT_VIEW_WIDTH, (THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE) * THUMBNAIL_COLUMN); | 189 | + picContainer_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT - (LABEL_POSITION_Y + LABEL_HEIGHT)); |
| 177 | picContainer_->SetStyle(STYLE_BACKGROUND_OPA, 0); | 190 | picContainer_->SetStyle(STYLE_BACKGROUND_OPA, 0); |
| 191 | + picContainer_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Silver().full); | ||
| 178 | rootView_->Add(picContainer_); | 192 | rootView_->Add(picContainer_); |
| 179 | 193 | ||
| 180 | picList_ = new UIViewGroup(); | 194 | picList_ = new UIViewGroup(); |
| @@ -190,23 +204,25 @@ void GalleryAbilitySlice::InitPictureList() | |||
| 190 | totalHeight += THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE; | 204 | totalHeight += THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE; |
| 191 | } | 205 | } |
| 192 | picList_->Resize(ROOT_VIEW_WIDTH, totalHeight); | 206 | picList_->Resize(ROOT_VIEW_WIDTH, totalHeight); |
| 193 | - printf("------------ totalHeight : %d ------------", totalHeight); | 207 | + LOGI("------------ totalHeight : %d ------------", totalHeight); |
| 194 | picContainer_->Add(picList_); | 208 | picContainer_->Add(picList_); |
| 195 | } | 209 | } |
| 196 | 210 | ||
| 197 | void GalleryAbilitySlice::AddAllPictures(const Point& pos, int16_t numInLine) | 211 | void GalleryAbilitySlice::AddAllPictures(const Point& pos, int16_t numInLine) |
| 198 | { | 212 | { |
| 199 | - printf("GalleryAbilitySlice::AddAllPictures | start | %d\n", numInLine); | 213 | + LOGI("GalleryAbilitySlice::AddAllPictures | start | %d", numInLine); |
| 200 | Point imagePos = pos; | 214 | Point imagePos = pos; |
| 201 | - DIR* drip = opendir(THUMBNAIL_DIRECTORY); | 215 | + LOGI("opendir: %s", PHOTO_DIRECTORY); |
| 216 | + DIR* drip = opendir(PHOTO_DIRECTORY); | ||
| 202 | if (drip == nullptr) { | 217 | if (drip == nullptr) { |
| 203 | return; | 218 | return; |
| 204 | } | 219 | } |
| 205 | struct dirent* info = nullptr; | 220 | struct dirent* info = nullptr; |
| 206 | while ((info = readdir(drip)) != nullptr && pictureCount_ < MAX_PICTURE_COUNT) { | 221 | while ((info = readdir(drip)) != nullptr && pictureCount_ < MAX_PICTURE_COUNT) { |
| 222 | + LOGI("readdir for: %s", info->d_name); | ||
| 207 | uint16_t imageNameLen = static_cast<uint16_t>(strlen(info->d_name)); | 223 | uint16_t imageNameLen = static_cast<uint16_t>(strlen(info->d_name)); |
| 208 | if (imageNameLen > MAX_PATH_LENGTH || (strcmp(info->d_name, ".") == 0) || (strcmp(info->d_name, "..") == 0)) { | 224 | if (imageNameLen > MAX_PATH_LENGTH || (strcmp(info->d_name, ".") == 0) || (strcmp(info->d_name, "..") == 0)) { |
| 209 | - printf("GalleryAbilitySlice::AddAllPictures | imageNameLen > MAX_PATH_LENGTH | %d\n", imageNameLen); | 225 | + LOGW("GalleryAbilitySlice::AddAllPictures | imageNameLen > MAX_PATH_LENGTH | %d", imageNameLen); |
| 210 | continue; | 226 | continue; |
| 211 | } | 227 | } |
| 212 | char* imageName = new char[imageNameLen + 1](); | 228 | char* imageName = new char[imageNameLen + 1](); |
| @@ -214,18 +230,19 @@ void GalleryAbilitySlice::AddAllPictures(const Point& pos, int16_t numInLine) | |||
| 214 | pictureName_[pictureCount_] = imageName; | 230 | pictureName_[pictureCount_] = imageName; |
| 215 | pictureCount_++; | 231 | pictureCount_++; |
| 216 | 232 | ||
| 217 | - uint16_t pathLen = static_cast<uint16_t>(strlen(THUMBNAIL_DIRECTORY)) + imageNameLen + 1; | 233 | + uint16_t pathLen = static_cast<uint16_t>(strlen(PHOTO_DIRECTORY)) + imageNameLen + 1; |
| 218 | if (pathLen > MAX_PATH_LENGTH) { | 234 | if (pathLen > MAX_PATH_LENGTH) { |
| 219 | - printf("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d\n", pathLen); | 235 | + LOGW("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d", pathLen); |
| 220 | continue; | 236 | continue; |
| 221 | } | 237 | } |
| 222 | char* imagePath = new char[pathLen + 1](); | 238 | char* imagePath = new char[pathLen + 1](); |
| 223 | - if (sprintf_s(imagePath, pathLen + 1, "%s/%s", THUMBNAIL_DIRECTORY, info->d_name) < 0) { | 239 | + if (sprintf_s(imagePath, pathLen + 1, "%s/%s", PHOTO_DIRECTORY, info->d_name) < 0) { |
| 224 | - printf("GalleryAbilitySlice::AddAllPictures | sprintf_s error\n"); | 240 | + LOGE("GalleryAbilitySlice::AddAllPictures | sprintf_s error"); |
| 225 | delete[] imagePath; | 241 | delete[] imagePath; |
| 226 | continue; | 242 | continue; |
| 227 | } | 243 | } |
| 228 | 244 | ||
| 245 | + LOGI("add image: pos:[%d, %d], name:%s, path:%s", imagePos.x, imagePos.y, imageName, imagePath); | ||
| 229 | picList_->Add(CreateImageItem(imagePos, imageName, imagePath)); | 246 | picList_->Add(CreateImageItem(imagePos, imageName, imagePath)); |
| 230 | delete[] imagePath; | 247 | delete[] imagePath; |
| 231 | 248 | ||
| @@ -245,15 +262,10 @@ UIView* GalleryAbilitySlice::CreateImageItem(const Point& pos, const char* image | |||
| 245 | UIImageView* imageView = new UIImageView(); | 262 | UIImageView* imageView = new UIImageView(); |
| 246 | imageView->SetAutoEnable(false); | 263 | imageView->SetAutoEnable(false); |
| 247 | imageView->Resize(THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y); | 264 | imageView->Resize(THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y); |
| 248 | - imageView->SetSrc(imagePath); | ||
| 249 | pictureOnClickListener_[pictureOnClickListenerCount_] = GetImageClickListener(imageName); | 265 | pictureOnClickListener_[pictureOnClickListenerCount_] = GetImageClickListener(imageName); |
| 250 | imageView->SetOnClickListener(pictureOnClickListener_[pictureOnClickListenerCount_++]); | 266 | imageView->SetOnClickListener(pictureOnClickListener_[pictureOnClickListenerCount_++]); |
| 251 | imageView->SetTouchable(true); | 267 | imageView->SetTouchable(true); |
| 252 | - | 268 | + imageView->SetResizeMode(UIImageView::FILL); |
| 253 | - if (strncmp(imageName, PHOTO_PREFIX, strlen(PHOTO_PREFIX)) == 0) { | ||
| 254 | - imageView->SetPosition(pos.x, pos.y); | ||
| 255 | - return imageView; | ||
| 256 | - } | ||
| 257 | imageView->SetPosition(0, 0); | 269 | imageView->SetPosition(0, 0); |
| 258 | 270 | ||
| 259 | UIViewGroup* imageItem = new UIViewGroup(); | 271 | UIViewGroup* imageItem = new UIViewGroup(); |
| @@ -261,15 +273,43 @@ UIView* GalleryAbilitySlice::CreateImageItem(const Point& pos, const char* image | |||
| 261 | imageItem->SetPosition(pos.x, pos.y, THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y); | 273 | imageItem->SetPosition(pos.x, pos.y, THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y); |
| 262 | imageItem->SetTouchable(true); | 274 | imageItem->SetTouchable(true); |
| 263 | imageItem->SetOnClickListener(imageView->GetOnClickListener()); | 275 | imageItem->SetOnClickListener(imageView->GetOnClickListener()); |
| 264 | - | ||
| 265 | - UIImageView* videoTag = new UIImageView(); | ||
| 266 | - videoTag->SetPosition(VIDEO_TAG_POSITION_X, VIDEO_TAG_POSITION_Y); | ||
| 267 | - videoTag->SetSrc(videoTagIconAbsolutePath); | ||
| 268 | - videoTag->SetTouchable(true); | ||
| 269 | - videoTag->SetOnClickListener(imageView->GetOnClickListener()); | ||
| 270 | - | ||
| 271 | imageItem->Add(imageView); | 276 | imageItem->Add(imageView); |
| 272 | - imageItem->Add(videoTag); | 277 | + |
| 278 | + std::string filePath(imagePath); | ||
| 279 | + if (filePath.find("mp4") != std::string::npos) { | ||
| 280 | + UIImageView* videoTag = new UIImageView(); | ||
| 281 | + std::string videoTagFielPath = videoTagIconAbsolutePath; | ||
| 282 | + videoTag->SetPosition(VIDEO_TAG_POSITION_X, VIDEO_TAG_POSITION_Y, VIDEO_TAG_WIDTH, VIDEO_TAG_HEIGHT); | ||
| 283 | + videoTag->SetTouchable(true); | ||
| 284 | + videoTag->SetOnClickListener(imageView->GetOnClickListener()); | ||
| 285 | + imageDecoder_->DecodeImage(videoTagFielPath, [videoTag, videoTagFielPath](ImageInfo imageInfo) { | ||
| 286 | + LOGI("do SetSrc for img, filePath:%s, dataSize:%u", videoTagFielPath.c_str(), imageInfo.dataSize); | ||
| 287 | + videoTag->SetSrc(&imageInfo); | ||
| 288 | + }); | ||
| 289 | + | ||
| 290 | + UILabel* labelView = new UILabel(); | ||
| 291 | + labelView->SetPosition(0, 0, THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y); | ||
| 292 | + labelView->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, | ||
| 293 | + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | ||
| 294 | + labelView->SetLineBreakMode(UILabel::LineBreakMode::LINE_BREAK_ELLIPSIS); | ||
| 295 | + labelView->SetFont(FONT_NAME, GALLERY_FONT_SIZE); | ||
| 296 | + labelView->SetStyle(STYLE_TEXT_COLOR, Color::White().full); | ||
| 297 | + labelView->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 298 | + labelView->SetText(imageName); | ||
| 299 | + | ||
| 300 | + imageItem->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); | ||
| 301 | + imageItem->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); | ||
| 302 | + imageItem->Add(videoTag); | ||
| 303 | + imageItem->Add(labelView); | ||
| 304 | + } else { | ||
| 305 | + std::string fileName = imageName; | ||
| 306 | + std::string filePath = imagePath; | ||
| 307 | + static int num = 0; | ||
| 308 | + imageDecoder_->DecodeImage(filePath, [imageView, filePath](ImageInfo imageInfo) { | ||
| 309 | + LOGI("do SetSrc for img, filePath:%s, dataSize:%u", filePath.c_str(), imageInfo.dataSize); | ||
| 310 | + imageView->SetSrc(&imageInfo); | ||
| 311 | + }); | ||
| 312 | + } | ||
| 273 | 313 | ||
| 274 | return imageItem; | 314 | return imageItem; |
| 275 | } | 315 | } |
| @@ -277,28 +317,29 @@ UIView* GalleryAbilitySlice::CreateImageItem(const Point& pos, const char* image | |||
| 277 | EventListener* GalleryAbilitySlice::GetImageClickListener(const char* path) | 317 | EventListener* GalleryAbilitySlice::GetImageClickListener(const char* path) |
| 278 | { | 318 | { |
| 279 | auto onClick = [this, path] (UIView& view, const Event& event) -> bool { | 319 | auto onClick = [this, path] (UIView& view, const Event& event) -> bool { |
| 280 | - printf("############ Next AS enter #############\n"); | 320 | + LOGI("############ Next AS enter #############"); |
| 281 | Want wantData = { nullptr }; | 321 | Want wantData = { nullptr }; |
| 282 | - printf("------- imagePath: %s \n", path); | 322 | + LOGI("------- imagePath: %s ", path); |
| 283 | bool ret = SetWantData(&wantData, path, strlen(path) + 1); | 323 | bool ret = SetWantData(&wantData, path, strlen(path) + 1); |
| 284 | if (!ret) { | 324 | if (!ret) { |
| 285 | - printf("############ SetWantData error #############\n"); | 325 | + LOGE("############ SetWantData error #############"); |
| 286 | return ret; | 326 | return ret; |
| 287 | } | 327 | } |
| 288 | AbilitySlice* nextSlice = nullptr; | 328 | AbilitySlice* nextSlice = nullptr; |
| 289 | - if (strncmp(path, PHOTO_PREFIX, strlen(PHOTO_PREFIX)) == 0) { | 329 | + std::string filePath(path); |
| 290 | - printf("--------- enter PictureAbilitySlice \n"); | 330 | + if (filePath.find("jpg") != std::string::npos) { |
| 331 | + LOGI("--------- enter PictureAbilitySlice"); | ||
| 291 | nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PictureAbilitySlice"); | 332 | nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PictureAbilitySlice"); |
| 292 | } else { | 333 | } else { |
| 293 | - printf("--------- enter PlayerAbilitySlice \n"); | 334 | + LOGI("--------- enter PlayerAbilitySlice"); |
| 294 | nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PlayerAbilitySlice"); | 335 | nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PlayerAbilitySlice"); |
| 295 | } | 336 | } |
| 296 | if (nextSlice == nullptr) { | 337 | if (nextSlice == nullptr) { |
| 297 | - printf("undefined nextSlice\n"); | 338 | + LOGW("undefined nextSlice"); |
| 298 | } else { | 339 | } else { |
| 299 | Present(*nextSlice, wantData); | 340 | Present(*nextSlice, wantData); |
| 300 | } | 341 | } |
| 301 | - printf("############ Next AS exit #############\n"); | 342 | + LOGI("############ Next AS exit #############"); |
| 302 | return true; | 343 | return true; |
| 303 | }; | 344 | }; |
| 304 | return new EventListener(onClick, nullptr); | 345 | return new EventListener(onClick, nullptr); |
| @@ -328,23 +369,23 @@ void GalleryAbilitySlice::DeleteAllFilesInDir(const char* path) | |||
| 328 | uint16_t fileNameLen = static_cast<uint16_t>(strlen(info->d_name)); | 369 | uint16_t fileNameLen = static_cast<uint16_t>(strlen(info->d_name)); |
| 329 | uint16_t pathLen = static_cast<uint16_t>(strlen(path)) + fileNameLen + 1; | 370 | uint16_t pathLen = static_cast<uint16_t>(strlen(path)) + fileNameLen + 1; |
| 330 | if (pathLen > MAX_PATH_LENGTH) { | 371 | if (pathLen > MAX_PATH_LENGTH) { |
| 331 | - printf("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d\n", pathLen); | 372 | + LOGW("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d", pathLen); |
| 332 | continue; | 373 | continue; |
| 333 | } | 374 | } |
| 334 | char* filePath = new char[pathLen + 1](); | 375 | char* filePath = new char[pathLen + 1](); |
| 335 | if (sprintf_s(filePath, pathLen + 1, "%s/%s", path, info->d_name) < 0) { | 376 | if (sprintf_s(filePath, pathLen + 1, "%s/%s", path, info->d_name) < 0) { |
| 336 | - printf("GalleryAbilitySlice::AddAllPictures | sprintf_s error\n"); | 377 | + LOGE("GalleryAbilitySlice::AddAllPictures | sprintf_s error"); |
| 337 | delete[] filePath; | 378 | delete[] filePath; |
| 338 | continue; | 379 | continue; |
| 339 | } | 380 | } |
| 340 | if (unlink(filePath) != 0) { | 381 | if (unlink(filePath) != 0) { |
| 341 | - printf("unlink file error | %s\n", filePath); | 382 | + LOGE("unlink file error | %s", filePath); |
| 342 | } | 383 | } |
| 343 | delete[] filePath; | 384 | delete[] filePath; |
| 344 | } | 385 | } |
| 345 | delete info; | 386 | delete info; |
| 346 | closedir(drip); | 387 | closedir(drip); |
| 347 | - printf("GalleryAbilitySlice::DeleteAllFilesInDir() | success | %s\n", path); | 388 | + LOGI("GalleryAbilitySlice::DeleteAllFilesInDir() | success | %s", path); |
| 348 | } | 389 | } |
| 349 | 390 | ||
| 350 | void GalleryAbilitySlice::OnStart(const Want &want) | 391 | void GalleryAbilitySlice::OnStart(const Want &want) |
| @@ -354,18 +395,20 @@ void GalleryAbilitySlice::OnStart(const Want &want) | |||
| 354 | rootView_ = RootView::GetWindowRootView(); | 395 | rootView_ = RootView::GetWindowRootView(); |
| 355 | rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y); | 396 | rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y); |
| 356 | rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT); | 397 | rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT); |
| 357 | - rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); | 398 | + rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); |
| 358 | 399 | ||
| 359 | const char* pathHeader = GetSrcPath(); | 400 | const char* pathHeader = GetSrcPath(); |
| 360 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { | 401 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { |
| 361 | - printf("GalleryAbilitySlice::OnStart | backIconAbsolutePath error"); | 402 | + LOGE("GalleryAbilitySlice::OnStart | backIconAbsolutePath error"); |
| 362 | return; | 403 | return; |
| 363 | } | 404 | } |
| 364 | if (sprintf_s(videoTagIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_TAG_ICON_PATH) < 0) { | 405 | if (sprintf_s(videoTagIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_TAG_ICON_PATH) < 0) { |
| 365 | - printf("GalleryAbilitySlice::OnStart | videoTagIconAbsolutePath error"); | 406 | + LOGE("GalleryAbilitySlice::OnStart | videoTagIconAbsolutePath error"); |
| 366 | return; | 407 | return; |
| 367 | } | 408 | } |
| 368 | 409 | ||
| 410 | + imageDecoder_ = new ImageDecoder(AbilityEventHandler::GetCurrentHandler(), 1); | ||
| 411 | + | ||
| 369 | InitTitle(); | 412 | InitTitle(); |
| 370 | InitPictureList(); | 413 | InitPictureList(); |
| 371 | SetUIContent(rootView_); | 414 | SetUIContent(rootView_); |
| @@ -373,25 +416,28 @@ void GalleryAbilitySlice::OnStart(const Want &want) | |||
| 373 | 416 | ||
| 374 | void GalleryAbilitySlice::OnInactive() | 417 | void GalleryAbilitySlice::OnInactive() |
| 375 | { | 418 | { |
| 376 | - printf("GalleryAbilitySlice::OnInactive\n"); | 419 | + LOGI("GalleryAbilitySlice::OnInactive"); |
| 377 | AbilitySlice::OnInactive(); | 420 | AbilitySlice::OnInactive(); |
| 378 | } | 421 | } |
| 379 | 422 | ||
| 380 | void GalleryAbilitySlice::OnActive(const Want &want) | 423 | void GalleryAbilitySlice::OnActive(const Want &want) |
| 381 | { | 424 | { |
| 382 | - printf("GalleryAbilitySlice::OnActive\n"); | 425 | + LOGI("GalleryAbilitySlice::OnActive"); |
| 383 | AbilitySlice::OnActive(want); | 426 | AbilitySlice::OnActive(want); |
| 427 | + if (!imageDecoder_->IsRunning()) { | ||
| 428 | + imageDecoder_->Start(); | ||
| 429 | + } | ||
| 384 | } | 430 | } |
| 385 | 431 | ||
| 386 | void GalleryAbilitySlice::OnBackground() | 432 | void GalleryAbilitySlice::OnBackground() |
| 387 | { | 433 | { |
| 388 | - printf("GalleryAbilitySlice::OnBackground\n"); | 434 | + LOGI("GalleryAbilitySlice::OnBackground"); |
| 389 | AbilitySlice::OnBackground(); | 435 | AbilitySlice::OnBackground(); |
| 390 | } | 436 | } |
| 391 | 437 | ||
| 392 | void GalleryAbilitySlice::OnStop() | 438 | void GalleryAbilitySlice::OnStop() |
| 393 | { | 439 | { |
| 394 | - printf("GalleryAbilitySlice::OnStop\n"); | 440 | + LOGI("GalleryAbilitySlice::OnStop"); |
| 395 | AbilitySlice::OnStop(); | 441 | AbilitySlice::OnStop(); |
| 396 | Clear(); | 442 | Clear(); |
| 397 | } | 443 | } |
| @@ -0,0 +1,222 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include <chrono> | ||
| 17 | +#include <iostream> | ||
| 18 | +#include <sstream> | ||
| 19 | + | ||
| 20 | +#include <ability_event_handler.h> | ||
| 21 | +#include <gfx_utils/file.h> | ||
| 22 | + | ||
| 23 | +#if ENABLE_JPEG | ||
| 24 | +#include "jpeglib.h" | ||
| 25 | +#endif | ||
| 26 | +#if ENABLE_PNG | ||
| 27 | +#include "png.h" | ||
| 28 | +#endif | ||
| 29 | +#include <imgdecode/file_img_decoder.h> | ||
| 30 | +#include <imgdecode/jpeg_img_decoder.h> | ||
| 31 | +#include <imgdecode/png_img_decoder.h> | ||
| 32 | + | ||
| 33 | +#include "image_decoder.h" | ||
| 34 | +#include "gallery_log.h" | ||
| 35 | + | ||
| 36 | +namespace OHOS { | ||
| 37 | + | ||
| 38 | +enum GalleryImageType { | ||
| 39 | + IMG_PNG, | ||
| 40 | + IMG_JPEG, | ||
| 41 | + IMG_GIF, | ||
| 42 | + IMG_UNKNOWN, | ||
| 43 | +}; | ||
| 44 | +const static uint8_t IMG_BYTES_TO_CHECK = 4; // 4: check 4 bytes of image file | ||
| 45 | + | ||
| 46 | +GalleryImageType CheckImgType(const char* src) | ||
| 47 | +{ | ||
| 48 | + char buf[IMG_BYTES_TO_CHECK] = {0}; | ||
| 49 | +#ifdef _WIN32 | ||
| 50 | + int32_t fd = open(src, O_RDONLY | O_BINARY); | ||
| 51 | +#else | ||
| 52 | + int32_t fd = open(src, O_RDONLY); | ||
| 53 | +#endif | ||
| 54 | + if (fd < 0) { | ||
| 55 | + LOGE("can't open %s\n", src); | ||
| 56 | + return IMG_UNKNOWN; | ||
| 57 | + } | ||
| 58 | + if (read(fd, buf, IMG_BYTES_TO_CHECK) != IMG_BYTES_TO_CHECK) { | ||
| 59 | + close(fd); | ||
| 60 | + return IMG_UNKNOWN; | ||
| 61 | + } | ||
| 62 | + close(fd); | ||
| 63 | +#if ENABLE_PNG | ||
| 64 | + if (!png_sig_cmp(reinterpret_cast<png_const_bytep>(buf), 0, IMG_BYTES_TO_CHECK)) { | ||
| 65 | + return IMG_PNG; | ||
| 66 | + } | ||
| 67 | +#endif | ||
| 68 | +#if ENABLE_JPEG | ||
| 69 | + // 0xFF 0xD8: JPEG file's header | ||
| 70 | + if ((static_cast<uint8_t>(buf[0]) == 0xFF) && (static_cast<uint8_t>(buf[1]) == 0xD8)) { | ||
| 71 | + return IMG_JPEG; | ||
| 72 | + } | ||
| 73 | +#endif | ||
| 74 | + if ((static_cast<uint8_t>(buf[0]) == 0x47) && (static_cast<uint8_t>(buf[1]) == 0x49) && | ||
| 75 | + (static_cast<uint8_t>(buf[2]) == 0x46)) { // 2: array index of GIF file's header | ||
| 76 | + return IMG_GIF; | ||
| 77 | + } | ||
| 78 | + return IMG_UNKNOWN; | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +ImageDecoder::ImageDecoder(AbilityEventHandler* handler, size_t threadCount) : isRunning_(false), | ||
| 82 | + maxThreadCount_(threadCount), | ||
| 83 | + eventHandler_(handler) | ||
| 84 | +{ | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +ImageDecoder::~ImageDecoder() | ||
| 88 | +{ | ||
| 89 | + Stop(); | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +void ImageDecoder::DecodeImage(const std::string& imagePath, std::function<void(ImageInfo)> uiCallback) | ||
| 93 | +{ | ||
| 94 | + std::lock_guard<std::mutex> lock(queueMutex_); | ||
| 95 | + taskQueue_.push({imagePath, uiCallback}); | ||
| 96 | + taskCond_.notify_one(); | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +void ImageDecoder::Start() | ||
| 100 | +{ | ||
| 101 | + isRunning_ = true; | ||
| 102 | + for (size_t i = 0; i < maxThreadCount_; ++i) { | ||
| 103 | + workerThreads_.emplace_back(&ImageDecoder::WorkerThread, this); | ||
| 104 | + } | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +void ImageDecoder::Stop() | ||
| 108 | +{ | ||
| 109 | + if (!isRunning_) return; | ||
| 110 | + | ||
| 111 | + isRunning_ = false; | ||
| 112 | + taskCond_.notify_all(); | ||
| 113 | + | ||
| 114 | + for (auto& thread : workerThreads_) { | ||
| 115 | + if (thread.joinable()) { | ||
| 116 | + thread.join(); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + workerThreads_.clear(); | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +bool ImageDecoder::IsRunning() | ||
| 123 | +{ | ||
| 124 | + return isRunning_; | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +bool ImageDecoder::TryGetTask(DecodeTask& task) | ||
| 128 | +{ | ||
| 129 | + std::unique_lock<std::mutex> lock(queueMutex_); | ||
| 130 | + taskCond_.wait(lock, [this]() { | ||
| 131 | + return !isRunning_ || !taskQueue_.empty(); | ||
| 132 | + }); | ||
| 133 | + | ||
| 134 | + if (isRunning_ && !taskQueue_.empty()) { | ||
| 135 | + task = std::move(taskQueue_.front()); | ||
| 136 | + taskQueue_.pop(); | ||
| 137 | + return true; | ||
| 138 | + } | ||
| 139 | + return false; | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +void ImageDecoder::HandleTask(const DecodeTask& task) | ||
| 143 | +{ | ||
| 144 | + if (!isRunning_) { | ||
| 145 | + return; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + ImageInfo imageInfo = DoDecode(task.imagePath); | ||
| 149 | + NotifyCallback(task, imageInfo); | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +void ImageDecoder::NotifyCallback(const DecodeTask& task, const ImageInfo& imageInfo) | ||
| 153 | +{ | ||
| 154 | + if (eventHandler_) { | ||
| 155 | + eventHandler_->PostTask([task, imageInfo]() { | ||
| 156 | + task.callback(imageInfo); | ||
| 157 | + }); | ||
| 158 | + } | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +void ImageDecoder::WorkerThread() | ||
| 162 | +{ | ||
| 163 | + pid_t tid = gettid(); | ||
| 164 | + LOGI("WorkerThread started, tid:%d", tid); | ||
| 165 | + while (isRunning_) { | ||
| 166 | + DecodeTask task; | ||
| 167 | + bool hasTask = TryGetTask(task); | ||
| 168 | + if (hasTask) { | ||
| 169 | + HandleTask(task); | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | + LOGI("WorkerThread exit, tid: %d", tid); | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +ImageInfo ImageDecoder::DoDecode(const std::string& imagePath) | ||
| 176 | +{ | ||
| 177 | + pid_t tid = gettid(); | ||
| 178 | + LOGI("DoDecode start. path: %s (tid:%d)", imagePath.c_str(), tid); | ||
| 179 | + FileImgDecoder::ImgResDsc desc = {0}; | ||
| 180 | + FileImgDecoder* decoder = nullptr; | ||
| 181 | + GalleryImageType type = CheckImgType(imagePath.c_str()); | ||
| 182 | + if (type == IMG_PNG) { | ||
| 183 | + decoder = &(PngImgDecoder::GetInstance()); | ||
| 184 | + } else if (type == IMG_JPEG) { | ||
| 185 | + decoder = &(JpegImgDecoder::GetInstance()); | ||
| 186 | + } else { | ||
| 187 | + LOGE("DoDecode imageType(%d) not supported!", type); | ||
| 188 | + return desc.imgInfo; | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + if (decoder == nullptr) { | ||
| 192 | + LOGE("DoDecode decoder is null"); | ||
| 193 | + return desc.imgInfo; | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + desc.path = imagePath.c_str(); | ||
| 197 | + RetCode ret = decoder->Open(desc); | ||
| 198 | + if (ret != RetCode::OK) { | ||
| 199 | + LOGE("DoDecode decoder open failed"); | ||
| 200 | + return desc.imgInfo; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + ret = decoder->GetHeader(desc); | ||
| 204 | + if (ret != RetCode::OK) { | ||
| 205 | + LOGE("DoDecode decoder get header failed"); | ||
| 206 | + decoder->Close(desc); | ||
| 207 | + return desc.imgInfo; | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + ret = decoder->ReadToCache(desc); | ||
| 211 | + if (ret != RetCode::OK) { | ||
| 212 | + LOGE("DoDecode decoder read to cache failed"); | ||
| 213 | + decoder->Close(desc); | ||
| 214 | + return desc.imgInfo; | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + LOGI("DoDecode end. path: %s (tid:%d) result:%d, imageInfo.data:%p", imagePath.c_str(), | ||
| 218 | + tid, ret, desc.imgInfo.data); | ||
| 219 | + return desc.imgInfo; | ||
| 220 | +} | ||
| 221 | +} | ||
| 222 | + | ||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "gallery_config.h" | 18 | #include "gallery_config.h" |
| 19 | #include "gfx_utils/file.h" | 19 | #include "gfx_utils/file.h" |
| 20 | #include "securec.h" | 20 | #include "securec.h" |
| 21 | +#include "gallery_log.h" | ||
| 21 | 22 | ||
| 22 | namespace OHOS { | 23 | namespace OHOS { |
| 23 | REGISTER_AS(PictureAbilitySlice) | 24 | REGISTER_AS(PictureAbilitySlice) |
| @@ -29,7 +30,7 @@ PictureAbilitySlice::~PictureAbilitySlice() | |||
| 29 | 30 | ||
| 30 | void PictureAbilitySlice::Clear() | 31 | void PictureAbilitySlice::Clear() |
| 31 | { | 32 | { |
| 32 | - printf("PictureAbilitySlice::Clear() | start \n"); | 33 | + LOGI("PictureAbilitySlice::Clear() | start"); |
| 33 | if (backIcon_ != nullptr) { | 34 | if (backIcon_ != nullptr) { |
| 34 | delete backIcon_; | 35 | delete backIcon_; |
| 35 | backIcon_ = nullptr; | 36 | backIcon_ = nullptr; |
| @@ -50,12 +51,12 @@ void PictureAbilitySlice::Clear() | |||
| 50 | RootView::DestroyWindowRootView(rootView_); | 51 | RootView::DestroyWindowRootView(rootView_); |
| 51 | rootView_ = nullptr; | 52 | rootView_ = nullptr; |
| 52 | } | 53 | } |
| 53 | - printf("PictureAbilitySlice::Clear() | end \n"); | 54 | + LOGI("PictureAbilitySlice::Clear() | end"); |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | -void PictureAbilitySlice::InitTitle() | 57 | +void PictureAbilitySlice::InitTitle(const char* imageName) |
| 57 | { | 58 | { |
| 58 | - printf("PictureAbilitySlice::InitTitle | start \n"); | 59 | + LOGI("PictureAbilitySlice::InitTitle | start"); |
| 59 | backIcon_ = new UIImageView(); | 60 | backIcon_ = new UIImageView(); |
| 60 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); | 61 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); |
| 61 | backIcon_->SetSrc(backIconAbsolutePath); | 62 | backIcon_->SetSrc(backIconAbsolutePath); |
| @@ -67,40 +68,50 @@ void PictureAbilitySlice::InitTitle() | |||
| 67 | backArea_->SetTouchable(true); | 68 | backArea_->SetTouchable(true); |
| 68 | 69 | ||
| 69 | auto onClick = [this] (UIView &view, const Event &event) -> bool { | 70 | auto onClick = [this] (UIView &view, const Event &event) -> bool { |
| 70 | - printf("############ terminate AS enter #############\n"); | 71 | + LOGI("############ terminate AS enter #############\n"); |
| 71 | Terminate(); | 72 | Terminate(); |
| 72 | - printf("############ terminate AS exit #############\n"); | 73 | + LOGI("############ terminate AS exit #############\n"); |
| 73 | return true; | 74 | return true; |
| 74 | }; | 75 | }; |
| 75 | backIconListener_ = new EventListener(onClick, nullptr); | 76 | backIconListener_ = new EventListener(onClick, nullptr); |
| 76 | backIcon_->SetOnClickListener(backIconListener_); | 77 | backIcon_->SetOnClickListener(backIconListener_); |
| 77 | backArea_->SetOnClickListener(backIconListener_); | 78 | backArea_->SetOnClickListener(backIconListener_); |
| 78 | 79 | ||
| 80 | + titleLabel_ = new UILabel(); | ||
| 81 | + titleLabel_->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_WIDTH, LABEL_HEIGHT); | ||
| 82 | + titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | ||
| 83 | + titleLabel_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); | ||
| 84 | + titleLabel_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); | ||
| 85 | + titleLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 86 | + titleLabel_->SetText(imageName); | ||
| 87 | + | ||
| 79 | backArea_->Add(backIcon_); | 88 | backArea_->Add(backIcon_); |
| 80 | rootView_->Add(backArea_); | 89 | rootView_->Add(backArea_); |
| 90 | + rootView_->Add(titleLabel_); | ||
| 81 | } | 91 | } |
| 82 | 92 | ||
| 83 | void PictureAbilitySlice::InitPicture(const char* path) | 93 | void PictureAbilitySlice::InitPicture(const char* path) |
| 84 | { | 94 | { |
| 85 | - printf("PictureAbilitySlice::InitPicture | start | %s\n", path); | 95 | + LOGI("PictureAbilitySlice::InitPicture | start | %s\n", path); |
| 86 | picture_ = new UIImageView(); | 96 | picture_ = new UIImageView(); |
| 87 | picture_->SetSrc(path); | 97 | picture_->SetSrc(path); |
| 88 | int16_t imageWidth = picture_->GetWidth(); | 98 | int16_t imageWidth = picture_->GetWidth(); |
| 89 | int16_t imageHeight = picture_->GetHeight(); | 99 | int16_t imageHeight = picture_->GetHeight(); |
| 100 | + LOGI("imageWidth:%d, imageHeight:%d", imageWidth, imageHeight); | ||
| 90 | if (imageWidth > ROOT_VIEW_WIDTH || imageHeight > ROOT_VIEW_HEIGHT) { | 101 | if (imageWidth > ROOT_VIEW_WIDTH || imageHeight > ROOT_VIEW_HEIGHT) { |
| 91 | TransformMap transMap(picture_->GetOrigRect()); | 102 | TransformMap transMap(picture_->GetOrigRect()); |
| 92 | float scaleWidth = 1.0; | 103 | float scaleWidth = 1.0; |
| 93 | float scaleHeight = 1.0; | 104 | float scaleHeight = 1.0; |
| 94 | if (imageWidth > ROOT_VIEW_WIDTH) { | 105 | if (imageWidth > ROOT_VIEW_WIDTH) { |
| 95 | scaleWidth = static_cast<float>(ROOT_VIEW_WIDTH) / imageWidth; | 106 | scaleWidth = static_cast<float>(ROOT_VIEW_WIDTH) / imageWidth; |
| 96 | - printf("########## scaleWidth: %f \n", scaleWidth); | 107 | + LOGI("########## scaleWidth: %f", scaleWidth); |
| 97 | } | 108 | } |
| 98 | if (imageHeight > ROOT_VIEW_HEIGHT) { | 109 | if (imageHeight > ROOT_VIEW_HEIGHT) { |
| 99 | scaleHeight = static_cast<float>(ROOT_VIEW_HEIGHT) / imageHeight; | 110 | scaleHeight = static_cast<float>(ROOT_VIEW_HEIGHT) / imageHeight; |
| 100 | - printf("########## scaleHeight: %f \n", scaleHeight); | 111 | + LOGI("########## scaleHeight: %f", scaleHeight); |
| 101 | } | 112 | } |
| 102 | float scale = (scaleWidth < scaleHeight) ? scaleWidth : scaleHeight; | 113 | float scale = (scaleWidth < scaleHeight) ? scaleWidth : scaleHeight; |
| 103 | - printf("########## scale: %f \n", scale); | 114 | + LOGI("########## scale: %f", scale); |
| 104 | transMap.Scale(Vector2<float>(scale, scale), Vector2<float>(0, 0)); | 115 | transMap.Scale(Vector2<float>(scale, scale), Vector2<float>(0, 0)); |
| 105 | picture_->SetTransformMap(transMap); | 116 | picture_->SetTransformMap(transMap); |
| 106 | picture_->SetTransformAlgorithm(TransformAlgorithm::NEAREST_NEIGHBOR); | 117 | picture_->SetTransformAlgorithm(TransformAlgorithm::NEAREST_NEIGHBOR); |
| @@ -109,7 +120,7 @@ void PictureAbilitySlice::InitPicture(const char* path) | |||
| 109 | } | 120 | } |
| 110 | int16_t imagePosX = (ROOT_VIEW_WIDTH - imageWidth) / 2; // 2: half | 121 | int16_t imagePosX = (ROOT_VIEW_WIDTH - imageWidth) / 2; // 2: half |
| 111 | int16_t imagePosY = (ROOT_VIEW_HEIGHT - imageHeight) / 2; // 2: half | 122 | int16_t imagePosY = (ROOT_VIEW_HEIGHT - imageHeight) / 2; // 2: half |
| 112 | - printf("########## image pos x: %d | y: %d \n", imagePosX, imagePosY); | 123 | + LOGI("########## image pos x: %d | y: %d", imagePosX, imagePosY); |
| 113 | picture_->SetPosition(imagePosX, imagePosY); | 124 | picture_->SetPosition(imagePosX, imagePosY); |
| 114 | 125 | ||
| 115 | rootView_->Add(picture_); | 126 | rootView_->Add(picture_); |
| @@ -117,23 +128,23 @@ void PictureAbilitySlice::InitPicture(const char* path) | |||
| 117 | 128 | ||
| 118 | void PictureAbilitySlice::OnStart(const Want &want) | 129 | void PictureAbilitySlice::OnStart(const Want &want) |
| 119 | { | 130 | { |
| 120 | - printf("######### PictureAbilitySlice::OnStart\n"); | 131 | + LOGI("######### PictureAbilitySlice::OnStart\n"); |
| 121 | - printf("receive the data -> %s\n", reinterpret_cast<char*>(want.data)); | 132 | + LOGI("receive the data -> %s\n", reinterpret_cast<char*>(want.data)); |
| 122 | AbilitySlice::OnStart(want); | 133 | AbilitySlice::OnStart(want); |
| 123 | 134 | ||
| 124 | rootView_ = RootView::GetWindowRootView(); | 135 | rootView_ = RootView::GetWindowRootView(); |
| 125 | rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y); | 136 | rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y); |
| 126 | rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT); | 137 | rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT); |
| 127 | - rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); | 138 | + rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); |
| 128 | 139 | ||
| 129 | uint16_t imagePathLen = strlen(PHOTO_DIRECTORY) + strlen(reinterpret_cast<char*>(want.data)) + 1; | 140 | uint16_t imagePathLen = strlen(PHOTO_DIRECTORY) + strlen(reinterpret_cast<char*>(want.data)) + 1; |
| 130 | if (imagePathLen > MAX_PATH_LENGTH) { | 141 | if (imagePathLen > MAX_PATH_LENGTH) { |
| 131 | - printf("---- imagePathLen > MAX_PATH_LENGTH | %d", imagePathLen); | 142 | + LOGI("---- imagePathLen > MAX_PATH_LENGTH | %d", imagePathLen); |
| 132 | return; | 143 | return; |
| 133 | } | 144 | } |
| 134 | char* imagePath = new char[imagePathLen + 1](); | 145 | char* imagePath = new char[imagePathLen + 1](); |
| 135 | if (sprintf_s(imagePath, imagePathLen + 1, "%s/%s", PHOTO_DIRECTORY, reinterpret_cast<char*>(want.data)) < 0) { | 146 | if (sprintf_s(imagePath, imagePathLen + 1, "%s/%s", PHOTO_DIRECTORY, reinterpret_cast<char*>(want.data)) < 0) { |
| 136 | - printf("PictureAbilitySlice::OnStart | imagePath\n"); | 147 | + LOGE("PictureAbilitySlice::OnStart | imagePath\n"); |
| 137 | delete[] imagePath; | 148 | delete[] imagePath; |
| 138 | imagePath = nullptr; | 149 | imagePath = nullptr; |
| 139 | return; | 150 | return; |
| @@ -141,14 +152,14 @@ void PictureAbilitySlice::OnStart(const Want &want) | |||
| 141 | 152 | ||
| 142 | const char* pathHeader = GetSrcPath(); | 153 | const char* pathHeader = GetSrcPath(); |
| 143 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { | 154 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { |
| 144 | - printf("PictureAbilitySlice::OnStart | backIconAbsolutePath\n"); | 155 | + LOGE("PictureAbilitySlice::OnStart | backIconAbsolutePath\n"); |
| 145 | delete[] imagePath; | 156 | delete[] imagePath; |
| 146 | imagePath = nullptr; | 157 | imagePath = nullptr; |
| 147 | return; | 158 | return; |
| 148 | } | 159 | } |
| 149 | 160 | ||
| 150 | InitPicture(imagePath); | 161 | InitPicture(imagePath); |
| 151 | - InitTitle(); | 162 | + InitTitle(reinterpret_cast<char*>(want.data)); |
| 152 | delete[] imagePath; | 163 | delete[] imagePath; |
| 153 | 164 | ||
| 154 | SetUIContent(rootView_); | 165 | SetUIContent(rootView_); |
| @@ -156,25 +167,25 @@ void PictureAbilitySlice::OnStart(const Want &want) | |||
| 156 | 167 | ||
| 157 | void PictureAbilitySlice::OnInactive() | 168 | void PictureAbilitySlice::OnInactive() |
| 158 | { | 169 | { |
| 159 | - printf("PictureAbilitySlice::OnInactive\n"); | 170 | + LOGI("PictureAbilitySlice::OnInactive\n"); |
| 160 | AbilitySlice::OnInactive(); | 171 | AbilitySlice::OnInactive(); |
| 161 | } | 172 | } |
| 162 | 173 | ||
| 163 | void PictureAbilitySlice::OnActive(const Want &want) | 174 | void PictureAbilitySlice::OnActive(const Want &want) |
| 164 | { | 175 | { |
| 165 | - printf("PictureAbilitySlice::OnActive\n"); | 176 | + LOGI("PictureAbilitySlice::OnActive\n"); |
| 166 | AbilitySlice::OnActive(want); | 177 | AbilitySlice::OnActive(want); |
| 167 | } | 178 | } |
| 168 | 179 | ||
| 169 | void PictureAbilitySlice::OnBackground() | 180 | void PictureAbilitySlice::OnBackground() |
| 170 | { | 181 | { |
| 171 | - printf("PictureAbilitySlice::OnBackground\n"); | 182 | + LOGI("PictureAbilitySlice::OnBackground\n"); |
| 172 | AbilitySlice::OnBackground(); | 183 | AbilitySlice::OnBackground(); |
| 173 | } | 184 | } |
| 174 | 185 | ||
| 175 | void PictureAbilitySlice::OnStop() | 186 | void PictureAbilitySlice::OnStop() |
| 176 | { | 187 | { |
| 177 | - printf("PictureAbilitySlice::OnStop\n"); | 188 | + LOGI("PictureAbilitySlice::OnStop\n"); |
| 178 | AbilitySlice::OnStop(); | 189 | AbilitySlice::OnStop(); |
| 179 | Clear(); | 190 | Clear(); |
| 180 | } | 191 | } |
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "ability_manager.h" | 21 | #include "ability_manager.h" |
| 22 | #include "components/ui_image_view.h" | 22 | #include "components/ui_image_view.h" |
| 23 | #include "gfx_utils/file.h" | 23 | #include "gfx_utils/file.h" |
| 24 | +#include "gallery_log.h" | ||
| 24 | 25 | ||
| 25 | using OHOS::Media::Player; | 26 | using OHOS::Media::Player; |
| 26 | using OHOS::Media::Source; | 27 | using OHOS::Media::Source; |
| @@ -32,11 +33,11 @@ REGISTER_AS(PlayerAbilitySlice) | |||
| 32 | 33 | ||
| 33 | PlayerAbilitySlice::~PlayerAbilitySlice() | 34 | PlayerAbilitySlice::~PlayerAbilitySlice() |
| 34 | { | 35 | { |
| 35 | - printf("################ ~PlayerAbilitySlice enter\n"); | 36 | + LOGI("################ ~PlayerAbilitySlice enter"); |
| 36 | 37 | ||
| 37 | /** released in DestoryPlayer(). */ | 38 | /** released in DestoryPlayer(). */ |
| 38 | 39 | ||
| 39 | - printf("################ ~PlayerAbilitySlice exit\n"); | 40 | + LOGI("################ ~PlayerAbilitySlice exit"); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | std::shared_ptr<Player> PlayerAbilitySlice::CreatePlayer() | 43 | std::shared_ptr<Player> PlayerAbilitySlice::CreatePlayer() |
| @@ -50,7 +51,7 @@ std::shared_ptr<Player> PlayerAbilitySlice::CreatePlayer() | |||
| 50 | 51 | ||
| 51 | void PlayerAbilitySlice::Clear() | 52 | void PlayerAbilitySlice::Clear() |
| 52 | { | 53 | { |
| 53 | - printf("PlayerAbilitySlice::Clear | enter\n"); | 54 | + LOGI("PlayerAbilitySlice::Clear | enter"); |
| 54 | if (backIconListener_ != nullptr) { | 55 | if (backIconListener_ != nullptr) { |
| 55 | delete backIconListener_; | 56 | delete backIconListener_; |
| 56 | backIconListener_ = nullptr; | 57 | backIconListener_ = nullptr; |
| @@ -103,7 +104,7 @@ void PlayerAbilitySlice::Clear() | |||
| 103 | RootView::DestroyWindowRootView(rootView_); | 104 | RootView::DestroyWindowRootView(rootView_); |
| 104 | rootView_ = nullptr; | 105 | rootView_ = nullptr; |
| 105 | } | 106 | } |
| 106 | - printf("PlayerAbilitySlice::Clear() | end\n"); | 107 | + LOGI("PlayerAbilitySlice::Clear() | end"); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | void PlayerAbilitySlice::ShowErrorTips() | 110 | void PlayerAbilitySlice::ShowErrorTips() |
| @@ -115,9 +116,10 @@ void PlayerAbilitySlice::ShowErrorTips() | |||
| 115 | errorTips_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); | 116 | errorTips_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); |
| 116 | errorTips_->SetText("视频播放错误"); | 117 | errorTips_->SetText("视频播放错误"); |
| 117 | 118 | ||
| 118 | - rootView_->Add(backArea_); | ||
| 119 | rootView_->Add(errorTips_); | 119 | rootView_->Add(errorTips_); |
| 120 | + rootView_->Add(backArea_); | ||
| 120 | rootView_->Add(backIcon_); | 121 | rootView_->Add(backIcon_); |
| 122 | + rootView_->Add(titleLabel_); | ||
| 121 | SetUIContent(rootView_); | 123 | SetUIContent(rootView_); |
| 122 | } | 124 | } |
| 123 | 125 | ||
| @@ -132,19 +134,21 @@ void PlayerAbilitySlice::SetUpRootView() | |||
| 132 | rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); | 134 | rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); |
| 133 | } | 135 | } |
| 134 | 136 | ||
| 135 | -void PlayerAbilitySlice::SetUpBackArea(const char* pathHeader) | 137 | +void PlayerAbilitySlice::SetUpBackArea(const char* pathHeader, const char* imageName) |
| 136 | { | 138 | { |
| 137 | auto onClick = [this] (UIView &view, const Event &event) -> bool { | 139 | auto onClick = [this] (UIView &view, const Event &event) -> bool { |
| 138 | - printf("############ PlayerAbilitySlice terminate AS enter #############\n"); | 140 | + LOGI("############ PlayerAbilitySlice terminate AS enter #############"); |
| 139 | Terminate(); | 141 | Terminate(); |
| 140 | - printf("############ PlayerAbilitySlice terminate AS exit #############\n"); | 142 | + LOGI("############ PlayerAbilitySlice terminate AS exit #############"); |
| 141 | return true; | 143 | return true; |
| 142 | }; | 144 | }; |
| 143 | backIcon_ = new UIImageView(); | 145 | backIcon_ = new UIImageView(); |
| 144 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); | 146 | backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y); |
| 147 | + backIcon_->SetStyle(STYLE_BACKGROUND_OPA, 0); | ||
| 148 | + backIcon_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); | ||
| 145 | 149 | ||
| 146 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { | 150 | if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) { |
| 147 | - printf("PlayerAbilitySlice::OnStart | backIconAbsolutePath | %s\n", pathHeader); | 151 | + LOGE("PlayerAbilitySlice::OnStart | backIconAbsolutePath | %s\n", pathHeader); |
| 148 | return; | 152 | return; |
| 149 | } | 153 | } |
| 150 | backIcon_->SetSrc(backIconAbsolutePath); | 154 | backIcon_->SetSrc(backIconAbsolutePath); |
| @@ -158,8 +162,17 @@ void PlayerAbilitySlice::SetUpBackArea(const char* pathHeader) | |||
| 158 | backArea_->SetTouchable(true); | 162 | backArea_->SetTouchable(true); |
| 159 | backArea_->SetOnClickListener(backIconListener_); | 163 | backArea_->SetOnClickListener(backIconListener_); |
| 160 | 164 | ||
| 165 | + titleLabel_ = new UILabel(); | ||
| 166 | + titleLabel_->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_WIDTH, LABEL_HEIGHT); | ||
| 167 | + titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | ||
| 168 | + titleLabel_->SetFont(FONT_NAME, GALLERY_FONT_SIZE); | ||
| 169 | + titleLabel_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); | ||
| 170 | + titleLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 171 | + titleLabel_->SetText(imageName); | ||
| 172 | + | ||
| 161 | rootView_->Add(backArea_); | 173 | rootView_->Add(backArea_); |
| 162 | rootView_->Add(backIcon_); | 174 | rootView_->Add(backIcon_); |
| 175 | + rootView_->Add(titleLabel_); | ||
| 163 | } | 176 | } |
| 164 | 177 | ||
| 165 | void PlayerAbilitySlice::SetUpVideoPlayer(const Want &want) | 178 | void PlayerAbilitySlice::SetUpVideoPlayer(const Want &want) |
| @@ -173,16 +186,16 @@ void PlayerAbilitySlice::SetUpVideoPlayer(const Want &want) | |||
| 173 | int8_t ret = sprintf_s(videoPlayer_->filePath, videoPathLen + 1, "%s/%s", VIDEO_SOURCE_DIRECTORY, | 186 | int8_t ret = sprintf_s(videoPlayer_->filePath, videoPathLen + 1, "%s/%s", VIDEO_SOURCE_DIRECTORY, |
| 174 | reinterpret_cast<char*>(want.data)); | 187 | reinterpret_cast<char*>(want.data)); |
| 175 | if (ret < 0) { | 188 | if (ret < 0) { |
| 176 | - printf("PlayerAbilitySlice::OnStart | videoPlayer_->filePath | %s\n", reinterpret_cast<char*>(want.data)); | 189 | + LOGE("PlayerAbilitySlice::OnStart | videoPlayer_->filePath | %s", reinterpret_cast<char*>(want.data)); |
| 177 | return; | 190 | return; |
| 178 | } | 191 | } |
| 179 | ret = sprintf_s(&videoPlayer_->filePath[videoPathLen - strlen(AVAILABEL_SOURCE_TYPE)], | 192 | ret = sprintf_s(&videoPlayer_->filePath[videoPathLen - strlen(AVAILABEL_SOURCE_TYPE)], |
| 180 | strlen(AVAILABEL_SOURCE_TYPE) + 1, "%s", AVAILABEL_SOURCE_TYPE); | 193 | strlen(AVAILABEL_SOURCE_TYPE) + 1, "%s", AVAILABEL_SOURCE_TYPE); |
| 181 | if (ret < 0) { | 194 | if (ret < 0) { |
| 182 | - printf("PlayerAbilitySlice::OnStart | videoPlayer_->filePath \n"); | 195 | + LOGE("PlayerAbilitySlice::OnStart | videoPlayer_->filePath"); |
| 183 | return; | 196 | return; |
| 184 | } | 197 | } |
| 185 | - printf("------########### mp4 file path | %s\n", videoPlayer_->filePath); | 198 | + LOGI("------########### mp4 file path | %s", videoPlayer_->filePath); |
| 186 | 199 | ||
| 187 | videoPlayer_->adapter = PlayerAbilitySlice::CreatePlayer(); | 200 | videoPlayer_->adapter = PlayerAbilitySlice::CreatePlayer(); |
| 188 | std::string uri(videoPlayer_->filePath); | 201 | std::string uri(videoPlayer_->filePath); |
| @@ -199,15 +212,14 @@ bool PlayerAbilitySlice::SetUpSurfaceView() | |||
| 199 | int32_t width = 0; | 212 | int32_t width = 0; |
| 200 | int32_t height = 0; | 213 | int32_t height = 0; |
| 201 | videoPlayer_->adapter->GetVideoWidth(width); | 214 | videoPlayer_->adapter->GetVideoWidth(width); |
| 202 | - printf("[%s,%d] width:%d\n", __func__, __LINE__, width); | ||
| 203 | videoPlayer_->adapter->GetVideoHeight(height); | 215 | videoPlayer_->adapter->GetVideoHeight(height); |
| 204 | - printf("[%s,%d] height:%d\n", __func__, __LINE__, height); | 216 | + LOGI("width:%d, height:%d", width, height); |
| 205 | 217 | ||
| 206 | if (width <= 0 || height <= 0) { | 218 | if (width <= 0 || height <= 0) { |
| 207 | videoPlayer_->adapter->Release(); | 219 | videoPlayer_->adapter->Release(); |
| 208 | delete videoPlayer_; | 220 | delete videoPlayer_; |
| 209 | videoPlayer_ = nullptr; | 221 | videoPlayer_ = nullptr; |
| 210 | - printf("******** width <= 0 || height <= 0 | return \n"); | 222 | + LOGE("******** width <= 0 || height <= 0 | return"); |
| 211 | ShowErrorTips(); | 223 | ShowErrorTips(); |
| 212 | return false; | 224 | return false; |
| 213 | } | 225 | } |
| @@ -263,7 +275,7 @@ void PlayerAbilitySlice::SetUpAnimatorGroup(const char* pathHeader) | |||
| 263 | { | 275 | { |
| 264 | int64_t duration = 0; | 276 | int64_t duration = 0; |
| 265 | videoPlayer_->adapter->GetDuration(duration); | 277 | videoPlayer_->adapter->GetDuration(duration); |
| 266 | - printf("[%s,%d] GetDuration:%lld\n", __func__, __LINE__, duration); | 278 | + LOGI("[%s,%d] GetDuration:%lld", __func__, __LINE__, duration); |
| 267 | 279 | ||
| 268 | animatorGroup_ = new UIViewGroup(); | 280 | animatorGroup_ = new UIViewGroup(); |
| 269 | animatorGroup_->SetPosition(0, ROOT_VIEW_HEIGHT - STATUS_BAR_GROUP_HEIGHT, | 281 | animatorGroup_->SetPosition(0, ROOT_VIEW_HEIGHT - STATUS_BAR_GROUP_HEIGHT, |
| @@ -313,12 +325,12 @@ void PlayerAbilitySlice::SetUpToggleButton(const char* pathHeader) | |||
| 313 | toggleButton_->SetState(true); | 325 | toggleButton_->SetState(true); |
| 314 | 326 | ||
| 315 | if (sprintf_s(videoPlayAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_PALY_PATH) < 0) { | 327 | if (sprintf_s(videoPlayAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_PALY_PATH) < 0) { |
| 316 | - printf("PlayerAbilitySlice::OnStart | videoPlayAbsolutePath\n"); | 328 | + LOGE("PlayerAbilitySlice::OnStart | videoPlayAbsolutePath"); |
| 317 | return; | 329 | return; |
| 318 | } | 330 | } |
| 319 | 331 | ||
| 320 | if (sprintf_s(videoPauseAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_PAUSE_PATH) < 0) { | 332 | if (sprintf_s(videoPauseAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_PAUSE_PATH) < 0) { |
| 321 | - printf("PlayerAbilitySlice::OnStart | videoPauseAbsolutePath\n"); | 333 | + LOGE("PlayerAbilitySlice::OnStart | videoPauseAbsolutePath"); |
| 322 | return; | 334 | return; |
| 323 | } | 335 | } |
| 324 | toggleButton_->SetImages(videoPauseAbsolutePath, videoPlayAbsolutePath); | 336 | toggleButton_->SetImages(videoPauseAbsolutePath, videoPlayAbsolutePath); |
| @@ -335,7 +347,7 @@ void PlayerAbilitySlice::SetUpToggleButton(const char* pathHeader) | |||
| 335 | 347 | ||
| 336 | void PlayerAbilitySlice::OnStart(const Want &want) | 348 | void PlayerAbilitySlice::OnStart(const Want &want) |
| 337 | { | 349 | { |
| 338 | - printf("@@@@@ PlayerAbilitySlice::OnStart\n"); | 350 | + LOGI("@@@@@ PlayerAbilitySlice::OnStart"); |
| 339 | AbilitySlice::OnStart(want); | 351 | AbilitySlice::OnStart(want); |
| 340 | 352 | ||
| 341 | SetUpRootView(); | 353 | SetUpRootView(); |
| @@ -347,7 +359,7 @@ void PlayerAbilitySlice::OnStart(const Want &want) | |||
| 347 | if (!SetUpSurfaceView()) { | 359 | if (!SetUpSurfaceView()) { |
| 348 | return; | 360 | return; |
| 349 | } | 361 | } |
| 350 | - SetUpBackArea(pathHeader); | 362 | + SetUpBackArea(pathHeader, reinterpret_cast<char*>(want.data)); |
| 351 | SetUpAnimatorGroup(pathHeader); | 363 | SetUpAnimatorGroup(pathHeader); |
| 352 | 364 | ||
| 353 | SetUIContent(rootView_); | 365 | SetUIContent(rootView_); |
| @@ -357,24 +369,24 @@ void PlayerAbilitySlice::OnStart(const Want &want) | |||
| 357 | animator_->SetToggleBtnListener(onClickListener_); | 369 | animator_->SetToggleBtnListener(onClickListener_); |
| 358 | animator_->Start(); | 370 | animator_->Start(); |
| 359 | 371 | ||
| 360 | - printf("## @@@@@ PlayerAbilitySlice::OnStart | end \n"); | 372 | + LOGI("## @@@@@ PlayerAbilitySlice::OnStart | end "); |
| 361 | } | 373 | } |
| 362 | 374 | ||
| 363 | void PlayerAbilitySlice::OnInactive() | 375 | void PlayerAbilitySlice::OnInactive() |
| 364 | { | 376 | { |
| 365 | - printf("PlayerAbilitySlice::OnInactive\n"); | 377 | + LOGI("PlayerAbilitySlice::OnInactive"); |
| 366 | AbilitySlice::OnInactive(); | 378 | AbilitySlice::OnInactive(); |
| 367 | } | 379 | } |
| 368 | 380 | ||
| 369 | void PlayerAbilitySlice::OnActive(const Want &want) | 381 | void PlayerAbilitySlice::OnActive(const Want &want) |
| 370 | { | 382 | { |
| 371 | - printf("PlayerAbilitySlice::OnActive\n"); | 383 | + LOGI("PlayerAbilitySlice::OnActive"); |
| 372 | AbilitySlice::OnActive(want); | 384 | AbilitySlice::OnActive(want); |
| 373 | } | 385 | } |
| 374 | 386 | ||
| 375 | void PlayerAbilitySlice::OnBackground() | 387 | void PlayerAbilitySlice::OnBackground() |
| 376 | { | 388 | { |
| 377 | - printf("PlayerAbilitySlice::OnBackground\n"); | 389 | + LOGI("PlayerAbilitySlice::OnBackground"); |
| 378 | AbilitySlice::OnBackground(); | 390 | AbilitySlice::OnBackground(); |
| 379 | } | 391 | } |
| 380 | 392 | ||
| @@ -393,7 +405,7 @@ void PlayerAbilitySlice::OnStop() | |||
| 393 | videoPlayer_ = nullptr; | 405 | videoPlayer_ = nullptr; |
| 394 | } | 406 | } |
| 395 | Clear(); | 407 | Clear(); |
| 396 | - printf("PlayerAbilitySlice::OnStop\n"); | 408 | + LOGI("PlayerAbilitySlice::OnStop"); |
| 397 | AbilitySlice::OnStop(); | 409 | AbilitySlice::OnStop(); |
| 398 | } | 410 | } |
| 399 | 411 | ||
| @@ -448,11 +460,11 @@ bool ToggleBtnListener::OnClick(UIView &view, const ClickEvent& event) | |||
| 448 | if (button_->GetState()) { | 460 | if (button_->GetState()) { |
| 449 | videoPlayer_->adapter->Play(); | 461 | videoPlayer_->adapter->Play(); |
| 450 | animator_->Resume(); | 462 | animator_->Resume(); |
| 451 | - printf("ToggleBtnListener::OnClick | play\n"); | 463 | + LOGI("ToggleBtnListener::OnClick | play"); |
| 452 | } else { | 464 | } else { |
| 453 | videoPlayer_->adapter->Pause(); | 465 | videoPlayer_->adapter->Pause(); |
| 454 | animator_->Pause(); | 466 | animator_->Pause(); |
| 455 | - printf("ToggleBtnListener::OnClick | pause\n"); | 467 | + LOGI("ToggleBtnListener::OnClick | pause"); |
| 456 | } | 468 | } |
| 457 | button_->Invalidate(); | 469 | button_->Invalidate(); |
| 458 | return true; | 470 | return true; |
| @@ -64,8 +64,9 @@ void AppInfo::SetButton(UILabelButton* button) | |||
| 64 | button->SetStyle(STYLE_BORDER_RADIUS, BUTTON_RADIUS); | 64 | button->SetStyle(STYLE_BORDER_RADIUS, BUTTON_RADIUS); |
| 65 | button->SetStyle(STYLE_BACKGROUND_OPA, TOTAL_OPACITY); | 65 | button->SetStyle(STYLE_BACKGROUND_OPA, TOTAL_OPACITY); |
| 66 | button->SetStyle(STYLE_BORDER_OPA, TOTAL_OPACITY); | 66 | button->SetStyle(STYLE_BORDER_OPA, TOTAL_OPACITY); |
| 67 | - button->SetStyle(STYLE_TEXT_COLOR, Color::ColorTo32(Color::White())); | 67 | + button->SetStyle(STYLE_TEXT_COLOR, Color::ColorTo32(Color::Black())); |
| 68 | button->SetImageSrc(appIconDir_, appIconDir_); | 68 | button->SetImageSrc(appIconDir_, appIconDir_); |
| 69 | + button->SetImagePosition(buttonHV_.x / BUTTON_IMAGE_POSITION_SCALE, buttonHV_.y / BUTTON_IMAGE_POSITION_SCALE); | ||
| 69 | button_ = button; | 70 | button_ = button; |
| 70 | } | 71 | } |
| 71 | 72 | ||
| @@ -112,7 +112,7 @@ void MainAbilitySlice::OnStart(const Want& want) | |||
| 112 | rootview_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); | 112 | rootview_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); |
| 113 | rootview_->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); | 113 | rootview_->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY); |
| 114 | rootview_->SetStyle(STYLE_BACKGROUND_COLOR, Color::ColorTo32(Color::GetColorFromRGB(0x30, 0x30, 0x30))); | 114 | rootview_->SetStyle(STYLE_BACKGROUND_COLOR, Color::ColorTo32(Color::GetColorFromRGB(0x30, 0x30, 0x30))); |
| 115 | - | 115 | + SetImageView(); |
| 116 | SetHead(); | 116 | SetHead(); |
| 117 | SetTail(); | 117 | SetTail(); |
| 118 | SetSwipe(); | 118 | SetSwipe(); |
| @@ -20,23 +20,24 @@ | |||
| 20 | #include <securec.h> | 20 | #include <securec.h> |
| 21 | 21 | ||
| 22 | namespace OHOS { | 22 | namespace OHOS { |
| 23 | -static constexpr int16_t LABLE_TITLE_HEIGHT = 30; // tail lable height | 23 | +constexpr int16_t LABLE_TITLE_HEIGHT = 30; // tail lable height |
| 24 | -static constexpr int16_t LABLE_TAIL_HEIGHT = 30; | 24 | +constexpr int16_t LABLE_TAIL_HEIGHT = 30; |
| 25 | -static constexpr int16_t APP_WIDTH_COUNT = 7; // blank + app + blank + app + blank | 25 | +constexpr int16_t APP_WIDTH_COUNT = 7; // blank + app + blank + app + blank |
| 26 | -static constexpr int16_t APP_HEIGHT_COUNT = 4; // app + lable + app + lable | 26 | +constexpr int16_t APP_HEIGHT_COUNT = 4; // app + lable + app + lable |
| 27 | -static constexpr int16_t MAX_VIEWGROUP = 3; // swipe window count | 27 | +constexpr int16_t MAX_VIEWGROUP = 1; // swipe window count |
| 28 | -static constexpr int16_t APP_ROW_COUNT = 2; // a swipe view app count in row | 28 | +constexpr int16_t APP_ROW_COUNT = 2; // a swipe view app count in row |
| 29 | -static constexpr int16_t APP_COL_COUNT = 3; // a sswipe view app count in col | 29 | +constexpr int16_t APP_COL_COUNT = 3; // a sswipe view app count in col |
| 30 | -static constexpr int16_t LAUNCHER_FOND_ID = 16; // other view fond id | 30 | +constexpr int16_t LAUNCHER_FOND_ID = 16; // other view fond id |
| 31 | -static constexpr int16_t APP_FOND_ID = 16; // app name fond id | 31 | +constexpr int16_t APP_FOND_ID = 16; // app name fond id |
| 32 | -static constexpr int16_t BIGLAUNCHER_FOND_ID = 48; // time big fond id | 32 | +constexpr int16_t BIGLAUNCHER_FOND_ID = 48; // time big fond id |
| 33 | -static constexpr int16_t TOTAL_OPACITY = 0; // transparent | 33 | +constexpr int16_t TOTAL_OPACITY = 0; // transparent |
| 34 | -static constexpr int16_t HALF_OPACITY = 50; // diaphanous | 34 | +constexpr int16_t HALF_OPACITY = 50; // diaphanous |
| 35 | -static constexpr int16_t UN_OPACITY = 255; // opaque | 35 | +constexpr int16_t UN_OPACITY = 255; // opaque |
| 36 | -static constexpr int16_t BUTTON_RADIUS = 20; // app icon radius | 36 | +constexpr int16_t BUTTON_RADIUS = 20; // app icon radius |
| 37 | -static constexpr int16_t LABLE_RADIUS = 0; // lable icon radius | 37 | +constexpr int16_t LABLE_RADIUS = 0; // lable icon radius |
| 38 | -static constexpr int16_t TITLE_LABLE_OPACITY = 255; // translucent | 38 | +constexpr int16_t TITLE_LABLE_OPACITY = 255; // translucent |
| 39 | -static constexpr int16_t GROUP_VIEW_RADIUS = 20; // view radius | 39 | +constexpr int16_t GROUP_VIEW_RADIUS = 20; // view radius |
| 40 | +constexpr int16_t BUTTON_IMAGE_POSITION_SCALE = 4; // scale factor for button image position | ||
| 40 | 41 | ||
| 41 | #ifndef TMP_BUF_SIZE | 42 | #ifndef TMP_BUF_SIZE |
| 42 | #define TMP_BUF_SIZE 128 | 43 | #define TMP_BUF_SIZE 128 |
| @@ -0,0 +1,101 @@ | |||
| 1 | +# Copyright (c) 2026 RKH Corp. | ||
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 3 | +# you may not use this file except in compliance with the License. | ||
| 4 | +# You may obtain a copy of the License at | ||
| 5 | +# | ||
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 7 | +# | ||
| 8 | +# Unless required by applicable law or agreed to in writing, software | ||
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 11 | +# See the License for the specific language governing permissions and | ||
| 12 | +# limitations under the License. | ||
| 13 | + | ||
| 14 | +import("//build/lite/config/hap_pack.gni") | ||
| 15 | + | ||
| 16 | +config("hilog_dir") { | ||
| 17 | + include_dirs = | ||
| 18 | + [ "//base/hiviewdfx/hilog_lite/interfaces/native/innerkits/hilog/" ] | ||
| 19 | +} | ||
| 20 | +config("hilog_lite_dir") { | ||
| 21 | + include_dirs = | ||
| 22 | + [ "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite/" ] | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +shared_library("recorder") { | ||
| 26 | + sources = [ | ||
| 27 | + "src/recorder_ability.cpp", | ||
| 28 | + "src/recorder_ability_main_slice.cpp", | ||
| 29 | + "src/recorder_list_adapter.cpp", | ||
| 30 | + "src/media_utils.cpp", | ||
| 31 | + ] | ||
| 32 | + | ||
| 33 | + include_dirs = [ | ||
| 34 | + "include", | ||
| 35 | + "${aafwk_lite_path}/interfaces/kits/ability_lite", | ||
| 36 | + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", | ||
| 37 | + "${aafwk_lite_path}/interfaces/kits/want_lite", | ||
| 38 | + "//foundation/multimedia/media_lite/interfaces/kits/player_lite", | ||
| 39 | + ] | ||
| 40 | + | ||
| 41 | + deps = [ | ||
| 42 | + "${aafwk_lite_path}/frameworks/ability_lite:aafwk_abilitykit_lite", | ||
| 43 | + "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", | ||
| 44 | + "//foundation/arkui/ui_lite:ui_lite", | ||
| 45 | + "//foundation/distributeddatamgr/kv_store/interfaces/inner_api/kv_store:kv_store", | ||
| 46 | + "//foundation/graphic/graphic_utils_lite:utils_lite", | ||
| 47 | + "//foundation/graphic/surface_lite", | ||
| 48 | + "//foundation/multimedia/media_lite/frameworks/player_lite:player_lite", | ||
| 49 | + "//foundation/multimedia/media_lite/frameworks/recorder_lite:recorder_lite", | ||
| 50 | + "//foundation/systemabilitymgr/samgr_lite/samgr:samgr", | ||
| 51 | + ] | ||
| 52 | + | ||
| 53 | + if (defined(ohos_lite)) { | ||
| 54 | + if (ohos_kernel_type == "liteos_m") { | ||
| 55 | + configs += [ ":hilog_lite_dir" ] | ||
| 56 | + deps += [ "//base/hiviewdfx/hilog_lite/frameworks/mini:hilog_lite" ] | ||
| 57 | + } else if (ohos_kernel_type == "liteos_a") { | ||
| 58 | + configs += [ ":hilog_dir" ] | ||
| 59 | + deps += [ | ||
| 60 | + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", | ||
| 61 | + "//third_party/bounds_checking_function:libsec_shared", | ||
| 62 | + ] | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + cflags = [ "-Wall" ] | ||
| 67 | + cflags_cc = cflags | ||
| 68 | + ldflags = [ "-shared" ] | ||
| 69 | + ldflags += [ "-lstdc++" ] | ||
| 70 | + ldflags += [ "-lpthread" ] | ||
| 71 | + ldflags += [ "-L$ohos_root_path/sysroot/usr/lib" ] | ||
| 72 | + ldflags += [ "-Wl,-rpath-link=$ohos_root_path/sysroot/usr/lib" ] | ||
| 73 | + ldflags += [ | ||
| 74 | + "-lui", | ||
| 75 | + "-lsurface", | ||
| 76 | + "-lplayer_lite", | ||
| 77 | + "-lability", | ||
| 78 | + ] | ||
| 79 | + | ||
| 80 | + defines = [ | ||
| 81 | + "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER", | ||
| 82 | + "ENABLE_WINDOW=1", | ||
| 83 | + "ABILITY_WINDOW_SUPPORT", | ||
| 84 | + "HILOG_ENABLE", | ||
| 85 | + # "USE_RECORDER_FD" | ||
| 86 | + "USE_RECORDER_API", | ||
| 87 | + "USE_PLAYER_API" | ||
| 88 | + ] | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +hap_pack("recorder_hap") { | ||
| 92 | + deps = [ ":recorder" ] | ||
| 93 | + mode = "hap" | ||
| 94 | + json_path = "config.json" | ||
| 95 | + ability_so_path = "$root_out_dir/librecorder.so" | ||
| 96 | + force = "true" | ||
| 97 | + cert_profile = "cert/recorder_AppProvision_Release.p7b" | ||
| 98 | + resources_path = "resources" | ||
| 99 | + hap_name = "recorder" | ||
| 100 | + privatekey = "HOS Application Provision Release" | ||
| 101 | +} | ||
Binary files do not support preview
| @@ -0,0 +1,89 @@ | |||
| 1 | +{ | ||
| 2 | + "app": { | ||
| 3 | + "bundleName": "com.ohos.recorder", | ||
| 4 | + "vendor": "ohos", | ||
| 5 | + "version": { | ||
| 6 | + "code": 1, | ||
| 7 | + "name": "1.0" | ||
| 8 | + }, | ||
| 9 | + "apiVersion": { | ||
| 10 | + "compatible": 3, | ||
| 11 | + "target": 4 | ||
| 12 | + } | ||
| 13 | + }, | ||
| 14 | + "deviceConfig": { | ||
| 15 | + "default": { | ||
| 16 | + } | ||
| 17 | + }, | ||
| 18 | + "module": { | ||
| 19 | + "package": "com.ohos.recorder", | ||
| 20 | + "name": ".MyHarmonyAbilityPackage", | ||
| 21 | + "deviceType": [ | ||
| 22 | + "phone", | ||
| 23 | + "tv", | ||
| 24 | + "tablet", | ||
| 25 | + "pc", | ||
| 26 | + "car", | ||
| 27 | + "smartWatch", | ||
| 28 | + "sportsWatch", | ||
| 29 | + "smartVision" | ||
| 30 | + ], | ||
| 31 | + "distro": { | ||
| 32 | + "deliveryWithInstall": true, | ||
| 33 | + "moduleName": "recorder", | ||
| 34 | + "moduleType": "entry" | ||
| 35 | + }, | ||
| 36 | + "abilities": [ | ||
| 37 | + { | ||
| 38 | + "name": "RecorderAbility", | ||
| 39 | + "icon": "assets/recorder/resources/drawable/recorder.png", | ||
| 40 | + "label": "test app 1", | ||
| 41 | + "launchType": "standard", | ||
| 42 | + "type": "page", | ||
| 43 | + "visible": true | ||
| 44 | + } | ||
| 45 | + ], | ||
| 46 | + "reqPermissions": [ | ||
| 47 | + { | ||
| 48 | + "name": "ohos.permission.MODIFY_AUDIO_SETTINGS", | ||
| 49 | + "reason": "SYSTEM_GRANT", | ||
| 50 | + "usedScene": { | ||
| 51 | + "ability": [ | ||
| 52 | + ".FormAbility" | ||
| 53 | + ], | ||
| 54 | + "when": "inuse" | ||
| 55 | + } | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + "name": "ohos.permission.READ_MEDIA", | ||
| 59 | + "reason": "USER_GRANT", | ||
| 60 | + "usedScene": { | ||
| 61 | + "ability": [ | ||
| 62 | + ".FormAbility" | ||
| 63 | + ], | ||
| 64 | + "when": "inuse" | ||
| 65 | + } | ||
| 66 | + }, | ||
| 67 | + { | ||
| 68 | + "name": "ohos.permission.READ_MEDIA_AUDIO", | ||
| 69 | + "reason": "USER_GRANT", | ||
| 70 | + "usedScene": { | ||
| 71 | + "ability": [ | ||
| 72 | + ".FormAbility" | ||
| 73 | + ], | ||
| 74 | + "when": "inuse" | ||
| 75 | + } | ||
| 76 | + }, | ||
| 77 | + { | ||
| 78 | + "name": "ohos.permission.MICROPHONE", | ||
| 79 | + "reason": "USER_GRANT", | ||
| 80 | + "usedScene": { | ||
| 81 | + "ability": [ | ||
| 82 | + ".FormAbility" | ||
| 83 | + ], | ||
| 84 | + "when": "inuse" | ||
| 85 | + } | ||
| 86 | + } | ||
| 87 | + ] | ||
| 88 | + } | ||
| 89 | +} | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_EVENT_LISTENER_H | ||
| 17 | +#define OHOS_EVENT_LISTENER_H | ||
| 18 | + | ||
| 19 | +#include <components/ui_view.h> | ||
| 20 | +#include <functional> | ||
| 21 | +#include <utility> | ||
| 22 | + | ||
| 23 | +namespace OHOS { | ||
| 24 | +using OnEventFunc = std::function<bool(UIView &view, const Event &event)>; | ||
| 25 | + | ||
| 26 | +class EventListener : | ||
| 27 | + public UIView::OnClickListener, | ||
| 28 | + public UIView::OnLongPressListener { | ||
| 29 | +public: | ||
| 30 | + EventListener() = delete; | ||
| 31 | + ~EventListener() override = default; | ||
| 32 | + | ||
| 33 | + EventListener(OnEventFunc onClick, OnEventFunc onLongPress) | ||
| 34 | + { | ||
| 35 | + onClick_ = std::move(onClick); | ||
| 36 | + onLongPress_ = std::move(onLongPress); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + bool OnClick(UIView& view, const ClickEvent &event) override | ||
| 40 | + { | ||
| 41 | + if (!onClick_) { | ||
| 42 | + return false; | ||
| 43 | + } | ||
| 44 | + UIView *currentView = &view; | ||
| 45 | + if (currentView == nullptr) { | ||
| 46 | + return false; | ||
| 47 | + } | ||
| 48 | + return onClick_(*currentView, event); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + bool OnLongPress(UIView& view, const LongPressEvent &event) override | ||
| 52 | + { | ||
| 53 | + if (!onLongPress_) { | ||
| 54 | + return false; | ||
| 55 | + } | ||
| 56 | + UIView *currentView = &view; | ||
| 57 | + if (currentView == nullptr) { | ||
| 58 | + return false; | ||
| 59 | + } | ||
| 60 | + return onLongPress_(*currentView, event); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | +private: | ||
| 64 | + OnEventFunc onClick_ {}; | ||
| 65 | + OnEventFunc onLongPress_ {}; | ||
| 66 | +}; | ||
| 67 | +} | ||
| 68 | +#endif // OHOS_EVENT_LISTENER_H | ||
| @@ -0,0 +1,80 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_MEDIA_UTILS_H | ||
| 17 | +#define OHOS_MEDIA_UTILS_H | ||
| 18 | + | ||
| 19 | +#include <memory> | ||
| 20 | + | ||
| 21 | +#ifdef USE_RECORDER_API | ||
| 22 | +#include <recorder.h> | ||
| 23 | +#endif | ||
| 24 | +#ifdef USE_PLAYER_API | ||
| 25 | +#include <player.h> | ||
| 26 | +#endif | ||
| 27 | + | ||
| 28 | +namespace OHOS { | ||
| 29 | +class MediaUtils { | ||
| 30 | +public: | ||
| 31 | + ~MediaUtils(); | ||
| 32 | + | ||
| 33 | + // Recorder | ||
| 34 | +#ifdef USE_RECORDER_API | ||
| 35 | + bool SetRecorderCallback(Media::RecorderCallback* recorderCallback); | ||
| 36 | +#endif | ||
| 37 | + bool StartRecord(); | ||
| 38 | + bool StopRecord(); | ||
| 39 | + | ||
| 40 | + // Player | ||
| 41 | +#ifdef USE_PLAYER_API | ||
| 42 | + bool SetPlayerCallback(Media::PlayerCallback* playerCallback); | ||
| 43 | +#endif | ||
| 44 | + bool StartPlay(const char* filePath); | ||
| 45 | + bool PausePlay(); | ||
| 46 | + bool StopPlay(); | ||
| 47 | + | ||
| 48 | +private: | ||
| 49 | + bool InitRecorder(); | ||
| 50 | + bool CloseRecorder(); | ||
| 51 | + bool MoveFiles(); | ||
| 52 | + bool EnsureRecorderDirectory(); | ||
| 53 | + bool StartRecorderService(); | ||
| 54 | + | ||
| 55 | + bool InitPlayer(const char* filePath); | ||
| 56 | + bool ClosePlayer(); | ||
| 57 | + | ||
| 58 | +private: | ||
| 59 | +#ifdef USE_RECORDER_API | ||
| 60 | + std::shared_ptr<Media::Recorder> recorder_; | ||
| 61 | + Media::RecorderCallback* recorderCallback_ { nullptr }; | ||
| 62 | + std::shared_ptr<Media::RecorderCallback> recorderCallbackPtr_; | ||
| 63 | +#endif | ||
| 64 | + | ||
| 65 | +#ifdef USE_PLAYER_API | ||
| 66 | + std::shared_ptr<Media::Player> player_; | ||
| 67 | + Media::PlayerCallback* playerCallback_ { nullptr }; | ||
| 68 | + std::shared_ptr<Media::PlayerCallback> playerCallbackPtr_; | ||
| 69 | +#endif | ||
| 70 | +#ifdef USE_RECORDER_FD | ||
| 71 | + int32_t recordFd_ = -1; | ||
| 72 | +#endif | ||
| 73 | + | ||
| 74 | + bool recording_ = false; | ||
| 75 | + bool playing_ = false; | ||
| 76 | + bool paused_ = false; | ||
| 77 | +}; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +#endif // OHOS_RECORDER_ABILITY_H | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_ABILITY_H | ||
| 17 | +#define OHOS_RECORDER_ABILITY_H | ||
| 18 | + | ||
| 19 | +#include <ability_loader.h> | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | +class RecorderAbility : public Ability { | ||
| 23 | +protected: | ||
| 24 | + void OnStart(const Want &want) override; | ||
| 25 | + void OnInactive() override; | ||
| 26 | + void OnActive(const Want &want) override; | ||
| 27 | + void OnBackground() override; | ||
| 28 | + void OnStop() override; | ||
| 29 | +}; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +#endif // OHOS_RECORDER_ABILITY_H | ||
| @@ -0,0 +1,120 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_ABILITY_MAIN_SLICE_H | ||
| 17 | +#define OHOS_RECORDER_ABILITY_MAIN_SLICE_H | ||
| 18 | + | ||
| 19 | +#include <ability_slice.h> | ||
| 20 | +#include <components/ui_image_view.h> | ||
| 21 | +#include <components/ui_label.h> | ||
| 22 | +#include <components/ui_list.h> | ||
| 23 | +#include <components/abstract_adapter.h> | ||
| 24 | +#include <event_listener.h> | ||
| 25 | + | ||
| 26 | +#include "recorder_config.h" | ||
| 27 | +#include "recorder_list_adapter.h" | ||
| 28 | +#include "media_utils.h" | ||
| 29 | +#include "task_helper.h" | ||
| 30 | + | ||
| 31 | +namespace OHOS { | ||
| 32 | +class RecorderAbilityMainSlice : public AbilitySlice, Media::PlayerCallback, Media::RecorderCallback { | ||
| 33 | +public: | ||
| 34 | + RecorderAbilityMainSlice() = default; | ||
| 35 | + ~RecorderAbilityMainSlice() override; | ||
| 36 | + | ||
| 37 | +public: | ||
| 38 | + // Media::PlayerCallback overrides | ||
| 39 | + void OnPlaybackComplete() override; | ||
| 40 | + void OnError(int32_t errorType, int32_t errorCode) override; | ||
| 41 | + void OnInfo(int type, int extra) override; | ||
| 42 | + void OnVideoSizeChanged(int width, int height) override {} | ||
| 43 | + void OnRewindToComplete() override {} | ||
| 44 | +protected: | ||
| 45 | + void OnStart(const Want &want) override; | ||
| 46 | + void OnInactive() override; | ||
| 47 | + void OnActive(const Want &want) override; | ||
| 48 | + void OnBackground() override; | ||
| 49 | + void OnStop() override; | ||
| 50 | + | ||
| 51 | +private: | ||
| 52 | + void InitTitle(); | ||
| 53 | + void InitRecordList(); | ||
| 54 | + void InitRecordCtrl(); | ||
| 55 | + void InitRecordLabels(); | ||
| 56 | + void InitRecordButtons(); | ||
| 57 | + void InitRecordListeners(); | ||
| 58 | + void AddRecordControlsToRoot(); | ||
| 59 | + bool InitImagePath(char* absolutePath, const char* pathHeader, const char* resourcePath, const char* errorTag); | ||
| 60 | + void InitRootView(); | ||
| 61 | + bool InitIconPaths(const char* pathHeader); | ||
| 62 | + void Start(); | ||
| 63 | + void Stop(); | ||
| 64 | + void Pause(); | ||
| 65 | + void Resume(); | ||
| 66 | + void Cancel(); | ||
| 67 | + | ||
| 68 | + // recorder timer | ||
| 69 | + void StartTimer(); | ||
| 70 | + void PauseTimer(); | ||
| 71 | + void ResumeTimer(); | ||
| 72 | + void StopTimer(); | ||
| 73 | + void UpdateRecordTime(); | ||
| 74 | + void UpdateDurationLabel(); | ||
| 75 | + | ||
| 76 | + void ReloadItems(); | ||
| 77 | + | ||
| 78 | + void OnItemPlay(int16_t index, const RecordItem& item); | ||
| 79 | + void OnItemDelete(int16_t index, const RecordItem& item); | ||
| 80 | + | ||
| 81 | + RootView* rootView_ { nullptr }; | ||
| 82 | + UIViewGroup* titleBar_ { nullptr }; | ||
| 83 | + UIImageView* backButton_ { nullptr }; | ||
| 84 | + EventListener* backButtonListener_ { nullptr }; | ||
| 85 | + UILabel* titleLabel_ { nullptr }; | ||
| 86 | + UILabel* noticeLabel_ { nullptr }; | ||
| 87 | + UILabel* durationLabel_ { nullptr }; | ||
| 88 | + UIImageView* fsImageView_ { nullptr }; | ||
| 89 | + | ||
| 90 | + UIImageView* startButton_ { nullptr }; // start/stop | ||
| 91 | + UIImageView* pauseButton_ { nullptr }; // pause/resume | ||
| 92 | + UIImageView* cancelButton_ { nullptr }; | ||
| 93 | + | ||
| 94 | + EventListener* startButtonListener_ { nullptr }; | ||
| 95 | + EventListener* stopButtonListener_ { nullptr }; | ||
| 96 | + EventListener* pauseButtonListener_ { nullptr }; | ||
| 97 | + EventListener* resumeButtonListener_ { nullptr }; | ||
| 98 | + EventListener* cancelButtonListener_ { nullptr }; | ||
| 99 | + | ||
| 100 | + UILabel* listLabel_ { nullptr }; | ||
| 101 | + UIList* list_ { nullptr }; | ||
| 102 | + RecorderListAdapter* adapter_ { nullptr }; | ||
| 103 | + std::string durationTime_; | ||
| 104 | + MediaUtils mediaUtils_; | ||
| 105 | + | ||
| 106 | + // recorder timer | ||
| 107 | + std::shared_ptr<Task> recordTimeUpdateTask_; | ||
| 108 | + uint32_t lastRecordTime_; | ||
| 109 | + uint32_t recordDuration_; | ||
| 110 | + | ||
| 111 | + char backIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 112 | + char fsIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 113 | + char startIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 114 | + char stopIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 115 | + char pauseIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 116 | + char resumeIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 117 | + char cancelIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 118 | +}; | ||
| 119 | +} | ||
| 120 | +#endif // OHOS_RECORDER_ABILITY_MAIN_SLICE_H | ||
| @@ -0,0 +1,52 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_ABILITY_SLICE_H | ||
| 17 | +#define OHOS_RECORDER_ABILITY_SLICE_H | ||
| 18 | + | ||
| 19 | +#include <ability_slice.h> | ||
| 20 | +#include <components/root_view.h> | ||
| 21 | +#include <components/ui_label.h> | ||
| 22 | +#include <components/ui_image_view.h> | ||
| 23 | +#include <event_listener.h> | ||
| 24 | + | ||
| 25 | +#include "recorder_config.h" | ||
| 26 | + | ||
| 27 | +namespace OHOS { | ||
| 28 | +class RecorderAbilitySlice : public AbilitySlice { | ||
| 29 | +public: | ||
| 30 | + RecorderAbilitySlice() = default; | ||
| 31 | + ~RecorderAbilitySlice() override; | ||
| 32 | +protected: | ||
| 33 | + void OnStart(const Want &want) override; | ||
| 34 | + void OnInactive() override; | ||
| 35 | + void OnActive(const Want &want) override; | ||
| 36 | + void OnBackground() override; | ||
| 37 | + void OnStop() override; | ||
| 38 | + | ||
| 39 | +private: | ||
| 40 | + void SetUpRootView(); | ||
| 41 | + void SetUpBackArea(); | ||
| 42 | + | ||
| 43 | +private: | ||
| 44 | + RootView* rootView_ { nullptr }; | ||
| 45 | + UIViewGroup* backArea_ { nullptr }; | ||
| 46 | + UIImageView* backIcon_ { nullptr }; | ||
| 47 | + UILabel* titleLabel_ { nullptr }; | ||
| 48 | + EventListener* backIconListener_ { nullptr }; | ||
| 49 | + char backIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 50 | +}; | ||
| 51 | +} // namespace OHOS | ||
| 52 | +#endif // OHOS_RECORDER_ABILITY_SLICE_H | ||
| @@ -0,0 +1,194 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_CONFIG_H | ||
| 17 | +#define OHOS_RECORDER_CONFIG_H | ||
| 18 | + | ||
| 19 | +#include "components/ui_view_group.h" | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | + | ||
| 23 | +/** icon resource file path */ | ||
| 24 | +static const char* const BACK_ICON_PATH = "/recorder/assets/recorder/resources/drawable/ic_back.png"; | ||
| 25 | +static const char* const FS_ICON_PATH = "/recorder/assets/recorder/resources/drawable/fs.png"; | ||
| 26 | +static const char* const START_ICON_PATH = "/recorder/assets/recorder/resources/drawable/start.png"; | ||
| 27 | +static const char* const STOP_ICON_PATH = "/recorder/assets/recorder/resources/drawable/stop.png"; | ||
| 28 | +static const char* const PAUSE_ICON_PATH = "/recorder/assets/recorder/resources/drawable/pause.png"; | ||
| 29 | +static const char* const RESUME_ICON_PATH = "/recorder/assets/recorder/resources/drawable/resume.png"; | ||
| 30 | +static const char* const CANCEL_ICON_PATH = "/recorder/assets/recorder/resources/drawable/cancel.png"; | ||
| 31 | +static const char* const LIST_FILE_ICON_PATH = "/recorder/assets/recorder/resources/drawable/list_file.png"; | ||
| 32 | +static const char* const LIST_PLAY_ICON_PATH = "/recorder/assets/recorder/resources/drawable/list_play.png"; | ||
| 33 | +static const char* const LIST_PAUSE_ICON_PATH = "/recorder/assets/recorder/resources/drawable/list_pause.png"; | ||
| 34 | +static const char* const LIST_DEL_ICON_PATH = "/recorder/assets/recorder/resources/drawable/list_del.png"; | ||
| 35 | + | ||
| 36 | +static constexpr int16_t MAX_PICTURE_COUNT = 256; | ||
| 37 | +static constexpr uint16_t MAX_PATH_LENGTH = 512; | ||
| 38 | +static constexpr uint16_t TIME_FIELD_WIDTH = 2; | ||
| 39 | + | ||
| 40 | +/** recorder folder path */ | ||
| 41 | +static const char* const RECORDER_DIRECTORY = "/userdata/audio/"; | ||
| 42 | +static const char* const RECORDER_TEMP_DIRECTORY = "/userdata/audio/norm/"; | ||
| 43 | +static const char* const RECORDER_TEMP_FILE_POSTFIX = ".MP4"; | ||
| 44 | +static const char* const RECORDER_FILE_POSTFIX = ".m4a"; | ||
| 45 | +static const char* const RECORDER_FILE_NAME_FMT = "%Y%m%d_%H%M%S"; | ||
| 46 | +static const char* const RECORDER_FILE_TIME_FMT = "%Y/%m/%d"; | ||
| 47 | +static constexpr uint16_t RECORDER_FILE_POSTFIX_LENGTH = 4; | ||
| 48 | + | ||
| 49 | +/** general page configuration */ | ||
| 50 | +static constexpr int ROOT_VIEW_X = 0; | ||
| 51 | +static constexpr int ROOT_VIEW_Y = 0; | ||
| 52 | +static constexpr int ROOT_VIEW_WIDTH = 1920; | ||
| 53 | +static constexpr int ROOT_VIEW_HEIGHT = 1080; | ||
| 54 | +static constexpr uint16_t ROOT_VIEW_OPACITY = 255; | ||
| 55 | + | ||
| 56 | +static const char* const FONT_NAME = "SourceHanSansSC-Regular.otf"; | ||
| 57 | + | ||
| 58 | +/** title bar */ | ||
| 59 | +static constexpr int16_t TITLE_BAR_X = 0; | ||
| 60 | +static constexpr int16_t TITLE_BAR_Y = 0; | ||
| 61 | +static constexpr int16_t TITLE_BAR_WIDTH = ROOT_VIEW_WIDTH; | ||
| 62 | +static constexpr int16_t TITLE_BAR_HEIGHT = 70; | ||
| 63 | +// title back icon | ||
| 64 | +static constexpr int16_t BACK_ICON_SIZE = 36; // 36 x 36 | ||
| 65 | +static constexpr int16_t BACK_ICON_PADDING_H = 30; | ||
| 66 | +static constexpr int16_t BACK_ICON_PADDING_V = (TITLE_BAR_HEIGHT - BACK_ICON_SIZE) / 2; | ||
| 67 | +static constexpr int16_t BACK_ICON_X = 0; | ||
| 68 | +static constexpr int16_t BACK_ICON_Y = TITLE_BAR_Y; | ||
| 69 | +static constexpr int16_t BACK_ICON_WIDTH = BACK_ICON_SIZE + BACK_ICON_PADDING_H * 2; | ||
| 70 | +static constexpr int16_t BACK_ICON_HEIGHT = TITLE_BAR_HEIGHT; | ||
| 71 | +// title label | ||
| 72 | +static constexpr int16_t TITLE_LABEL_X = BACK_ICON_X + BACK_ICON_SIZE + BACK_ICON_PADDING_H * 2; | ||
| 73 | +static constexpr int16_t TITLE_LABEL_Y = 0; | ||
| 74 | +static constexpr int16_t TITLE_LABEL_WIDTH = 100; | ||
| 75 | +static constexpr int16_t TITLE_LABEL_HEIGHT = TITLE_BAR_HEIGHT; | ||
| 76 | +static constexpr uint16_t TITLE_LABEL_FONT_SIZE = 25; | ||
| 77 | + | ||
| 78 | +/** notice label **/ | ||
| 79 | +static constexpr int16_t NOTICE_LABEL_WIDTH = 400; | ||
| 80 | +static constexpr int16_t NOTICE_LABEL_HEIGHT = 36; | ||
| 81 | +static constexpr int16_t NOTICE_LABEL_MARGIN_TOP = 30; | ||
| 82 | +static constexpr int16_t NOTICE_LABEL_X = (ROOT_VIEW_WIDTH - NOTICE_LABEL_WIDTH) / 2; | ||
| 83 | +static constexpr int16_t NOTICE_LABEL_Y = TITLE_BAR_Y + TITLE_BAR_HEIGHT + NOTICE_LABEL_MARGIN_TOP; | ||
| 84 | +static constexpr uint16_t NOTICE_LABEL_FONT_SIZE = 32; | ||
| 85 | + | ||
| 86 | +/** duration **/ | ||
| 87 | +static constexpr int16_t DURATION_LABEL_WIDTH = 400; | ||
| 88 | +static constexpr int16_t DURATION_LABEL_HEIGHT = 50; | ||
| 89 | +static constexpr int16_t DURATION_LABEL_MARGIN_TOP = 30; | ||
| 90 | +static constexpr int16_t DURATION_LABEL_X = (ROOT_VIEW_WIDTH - DURATION_LABEL_WIDTH) / 2; | ||
| 91 | +static constexpr int16_t DURATION_LABEL_Y = NOTICE_LABEL_Y + NOTICE_LABEL_HEIGHT + DURATION_LABEL_MARGIN_TOP; | ||
| 92 | +static constexpr uint16_t DURATION_LABEL_FONT_SIZE = 48; | ||
| 93 | + | ||
| 94 | +/** fs **/ | ||
| 95 | +static constexpr int16_t FS_IMAGE_WIDTH = 260; | ||
| 96 | +static constexpr int16_t FS_IMAGE_HEIGHT = 110; | ||
| 97 | +static constexpr int16_t FS_IMAGE_MARGIN_TOP = 40; | ||
| 98 | +static constexpr int16_t FS_IMAGE_X = (ROOT_VIEW_WIDTH - FS_IMAGE_WIDTH) / 2; | ||
| 99 | +static constexpr int16_t FS_IMAGE_Y = DURATION_LABEL_Y + DURATION_LABEL_HEIGHT + FS_IMAGE_MARGIN_TOP; | ||
| 100 | + | ||
| 101 | +/** start/stop button */ | ||
| 102 | +static constexpr int16_t START_BUTTON_SIZE = 140; | ||
| 103 | +static constexpr int16_t START_BUTTON_WIDTH = START_BUTTON_SIZE; | ||
| 104 | +static constexpr int16_t START_BUTTON_HEIGHT = START_BUTTON_SIZE; | ||
| 105 | +static constexpr int16_t START_BUTTON_MARGIN_TOP = 40; | ||
| 106 | +static constexpr int16_t START_BUTTON_X = (ROOT_VIEW_WIDTH - START_BUTTON_WIDTH) / 2; | ||
| 107 | +static constexpr int16_t START_BUTTON_Y = FS_IMAGE_Y + FS_IMAGE_HEIGHT + START_BUTTON_MARGIN_TOP; | ||
| 108 | + | ||
| 109 | +/** cancel button */ | ||
| 110 | +static constexpr int16_t CANCEL_BUTTON_SIZE = 80; | ||
| 111 | +static constexpr int16_t CANCEL_BUTTON_WIDTH = CANCEL_BUTTON_SIZE; | ||
| 112 | +static constexpr int16_t CANCEL_BUTTON_HEIGHT = CANCEL_BUTTON_SIZE; | ||
| 113 | +static constexpr int16_t CANCEL_BUTTON_MARGIN_RIGHT = 40; | ||
| 114 | +static constexpr int16_t CANCEL_BUTTON_X = START_BUTTON_X - CANCEL_BUTTON_WIDTH - CANCEL_BUTTON_MARGIN_RIGHT; | ||
| 115 | +static constexpr int16_t CANCEL_BUTTON_Y = START_BUTTON_Y; | ||
| 116 | + | ||
| 117 | +/** pause/resume button */ | ||
| 118 | +static constexpr int16_t PAUSE_BUTTON_SIZE = CANCEL_BUTTON_SIZE; | ||
| 119 | +static constexpr int16_t PAUSE_BUTTON_WIDTH = PAUSE_BUTTON_SIZE; | ||
| 120 | +static constexpr int16_t PAUSE_BUTTON_HEIGHT = PAUSE_BUTTON_SIZE; | ||
| 121 | +static constexpr int16_t PAUSE_BUTTON_MARGIN_LEFT = CANCEL_BUTTON_MARGIN_RIGHT; | ||
| 122 | +static constexpr int16_t PAUSE_BUTTON_X = START_BUTTON_X + START_BUTTON_WIDTH + PAUSE_BUTTON_MARGIN_LEFT; | ||
| 123 | +static constexpr int16_t PAUSE_BUTTON_Y = START_BUTTON_Y; | ||
| 124 | + | ||
| 125 | +/** list */ | ||
| 126 | +static constexpr int16_t LIST_MARGIN_H = 20; | ||
| 127 | +// list lable | ||
| 128 | +static constexpr int16_t LIST_LABEL_MARGIN_TOP = 20; | ||
| 129 | +static constexpr int16_t LIST_LABEL_X = LIST_MARGIN_H; | ||
| 130 | +static constexpr int16_t LIST_LABEL_Y = START_BUTTON_Y + START_BUTTON_HEIGHT + LIST_LABEL_MARGIN_TOP; | ||
| 131 | +static constexpr int16_t LIST_LABEL_WIDTH = 200; | ||
| 132 | +static constexpr int16_t LIST_LABEL_HEIGHT = 36; | ||
| 133 | +static constexpr uint16_t LIST_LABEL_FONT_SIZE = 32; | ||
| 134 | +// list | ||
| 135 | +static constexpr int16_t LIST_MARGIN_TOP = 20; | ||
| 136 | +static constexpr int16_t LIST_MARGIN_BOTTOM = 20; | ||
| 137 | +static constexpr int16_t LIST_X = LIST_MARGIN_H; | ||
| 138 | +static constexpr int16_t LIST_Y = LIST_LABEL_Y + LIST_LABEL_HEIGHT + LIST_MARGIN_TOP; | ||
| 139 | +static constexpr int16_t LIST_WIDTH = ROOT_VIEW_WIDTH - (LIST_MARGIN_H * 2); | ||
| 140 | +static constexpr int16_t LIST_HEIGHT = ROOT_VIEW_HEIGHT - LIST_MARGIN_BOTTOM - LIST_Y; | ||
| 141 | +// list divider | ||
| 142 | +static constexpr int16_t LIST_DIVIDER_HEIGHT = 8; | ||
| 143 | +// list item | ||
| 144 | +static constexpr int16_t LIST_ITEM_X = 0; | ||
| 145 | +static constexpr int16_t LIST_ITEM_Y = 0; | ||
| 146 | +static constexpr int16_t LIST_ITEM_WIDTH = LIST_WIDTH; | ||
| 147 | +static constexpr int16_t LIST_ITEM_HEIGHT = 110; | ||
| 148 | +static constexpr int16_t LIST_ITEM_PADDING_H = 20; | ||
| 149 | +static constexpr int16_t LIST_ITEM_PADDING_V = 20; | ||
| 150 | +// list item file icon | ||
| 151 | +static constexpr int16_t LIST_ITEM_FILE_ICON_X = LIST_ITEM_PADDING_H; | ||
| 152 | +static constexpr int16_t LIST_ITEM_FILE_ICON_Y = LIST_ITEM_PADDING_V; | ||
| 153 | +static constexpr int16_t LIST_ITEM_FILE_ICON_WIDTH = 72; | ||
| 154 | +static constexpr int16_t LIST_ITEM_FILE_ICON_HEIGHT = 72; | ||
| 155 | +// list item name label | ||
| 156 | +static constexpr int16_t LIST_ITEM_NAME_LABEL_MARGIN_LEFT = 20; | ||
| 157 | +static constexpr int16_t LIST_ITEM_NAME_LABEL_X = | ||
| 158 | + LIST_ITEM_FILE_ICON_X + LIST_ITEM_FILE_ICON_WIDTH + LIST_ITEM_NAME_LABEL_MARGIN_LEFT; | ||
| 159 | +static constexpr int16_t LIST_ITEM_NAME_LABEL_WIDTH = 500; | ||
| 160 | +static constexpr int16_t LIST_ITEM_NAME_LABEL_HEIGHT = 28; | ||
| 161 | +static constexpr uint16_t LIST_ITEM_NAME_LABEL_FONT_SIZE = 24; | ||
| 162 | +// list item time label | ||
| 163 | +static constexpr int16_t LIST_ITEM_TIME_PADDING_TOP = 10; | ||
| 164 | +static constexpr int16_t LIST_ITEM_TIME_LABEL_X = LIST_ITEM_NAME_LABEL_X; | ||
| 165 | +static constexpr int16_t LIST_ITEM_TIME_LABEL_WIDTH = 200; | ||
| 166 | +static constexpr int16_t LIST_ITEM_TIME_LABEL_HEIGHT = 22; | ||
| 167 | +static constexpr uint16_t LIST_ITEM_TIME_LABEL_FONT_SIZE = 20; | ||
| 168 | +// refactor list time name/time label Y | ||
| 169 | +static constexpr int16_t LIST_ITEM_NAME_LABEL_Y = | ||
| 170 | + (LIST_ITEM_HEIGHT - | ||
| 171 | + (LIST_ITEM_NAME_LABEL_HEIGHT + LIST_ITEM_TIME_PADDING_TOP + LIST_ITEM_TIME_LABEL_HEIGHT)) / | ||
| 172 | + 2; | ||
| 173 | +static constexpr int16_t LIST_ITEM_TIME_LABEL_Y = | ||
| 174 | + LIST_ITEM_NAME_LABEL_Y + LIST_ITEM_NAME_LABEL_HEIGHT + LIST_ITEM_TIME_PADDING_TOP; | ||
| 175 | +// list item play button | ||
| 176 | +static constexpr int16_t LIST_ITEM_BUTTON_SIZE = 56; | ||
| 177 | +static constexpr int16_t LIST_ITEM_BUTTON_MARGIN = 20; | ||
| 178 | +static constexpr int16_t LIST_ITEM_BORDER_RADIUS = 16; | ||
| 179 | +static constexpr int16_t LIST_ITEM_PLAY_BUTTON_X = | ||
| 180 | + LIST_ITEM_WIDTH - LIST_ITEM_PADDING_H - LIST_ITEM_BUTTON_SIZE * 2 - LIST_ITEM_BUTTON_MARGIN; | ||
| 181 | +static constexpr int16_t LIST_ITEM_PLAY_BUTTON_Y = (LIST_ITEM_HEIGHT - LIST_ITEM_BUTTON_SIZE) / 2; | ||
| 182 | +static constexpr int16_t LIST_ITEM_PLAY_BUTTON_WIDTH = LIST_ITEM_BUTTON_SIZE; | ||
| 183 | +static constexpr int16_t LIST_ITEM_PLAY_BUTTON_HEIGHT = LIST_ITEM_BUTTON_SIZE; | ||
| 184 | +// list item delete button | ||
| 185 | +static constexpr int16_t LIST_ITEM_DEL_BUTTON_X = LIST_ITEM_WIDTH - LIST_ITEM_PADDING_H - LIST_ITEM_BUTTON_SIZE; | ||
| 186 | +static constexpr int16_t LIST_ITEM_DEL_BUTTON_Y = (LIST_ITEM_HEIGHT - LIST_ITEM_BUTTON_SIZE) / 2; | ||
| 187 | +static constexpr int16_t LIST_ITEM_DEL_BUTTON_WIDTH = LIST_ITEM_BUTTON_SIZE; | ||
| 188 | +static constexpr int16_t LIST_ITEM_DEL_BUTTON_HEIGHT = LIST_ITEM_BUTTON_SIZE; | ||
| 189 | + | ||
| 190 | + | ||
| 191 | +/** prefix and File Type */ | ||
| 192 | +static const char* const AVAILABEL_SOURCE_TYPE = ".aac"; | ||
| 193 | +} // namespace OHOS | ||
| 194 | +#endif // OHOS_RECORDER_CONFIG_H | ||
| @@ -0,0 +1,125 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_LIST_ADAPTER_H | ||
| 17 | +#define OHOS_RECORDER_LIST_ADAPTER_H | ||
| 18 | + | ||
| 19 | +#include <components/ui_view.h> | ||
| 20 | +#include <components/ui_image_view.h> | ||
| 21 | +#include <components/ui_label.h> | ||
| 22 | +#include <components/abstract_adapter.h> | ||
| 23 | +#include <event_listener.h> | ||
| 24 | + | ||
| 25 | +#include <vector> | ||
| 26 | +#include <functional> | ||
| 27 | +#include <memory> | ||
| 28 | + | ||
| 29 | +#include "recorder_config.h" | ||
| 30 | + | ||
| 31 | +namespace OHOS { | ||
| 32 | +struct RecordItem { | ||
| 33 | + std::string name; // file name | ||
| 34 | + std::string path; // file path | ||
| 35 | + std::string timeStr; | ||
| 36 | + long time; // create time. | ||
| 37 | + bool started; // play started status | ||
| 38 | + bool paused; // paused status | ||
| 39 | +}; | ||
| 40 | + | ||
| 41 | +class OnItemPlayListener : public HeapBase { | ||
| 42 | +public: | ||
| 43 | + virtual void OnItemPlay(int16_t index, const RecordItem& item) = 0; | ||
| 44 | + virtual ~OnItemPlayListener() = default; | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +class OnItemDeleteListener : public HeapBase { | ||
| 48 | +public: | ||
| 49 | + virtual void OnItemDelete(int16_t index, const RecordItem& item) = 0; | ||
| 50 | + virtual ~OnItemDeleteListener() = default; | ||
| 51 | +}; | ||
| 52 | + | ||
| 53 | + | ||
| 54 | +using OnItemFunc = std::function<void(int16_t index, const RecordItem& item)>; | ||
| 55 | + | ||
| 56 | +class RecorderListItemListener : | ||
| 57 | + public OnItemPlayListener, | ||
| 58 | + public OnItemDeleteListener { | ||
| 59 | +public: | ||
| 60 | + RecorderListItemListener() = delete; | ||
| 61 | + ~RecorderListItemListener() override = default; | ||
| 62 | + | ||
| 63 | + RecorderListItemListener(OnItemFunc onPlay, OnItemFunc onDelete) | ||
| 64 | + { | ||
| 65 | + onPlay_ = std::move(onPlay); | ||
| 66 | + onDelete_ = std::move(onDelete); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + void OnItemPlay(int16_t index, const RecordItem& item) override | ||
| 70 | + { | ||
| 71 | + if (!onPlay_) { | ||
| 72 | + return; | ||
| 73 | + } | ||
| 74 | + onPlay_(index, item); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + void OnItemDelete(int16_t index, const RecordItem& item) override | ||
| 78 | + { | ||
| 79 | + if (!onDelete_) { | ||
| 80 | + return; | ||
| 81 | + } | ||
| 82 | + onDelete_(index, item); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | +private: | ||
| 86 | + OnItemFunc onPlay_ {}; | ||
| 87 | + OnItemFunc onDelete_ {}; | ||
| 88 | +}; | ||
| 89 | + | ||
| 90 | + | ||
| 91 | +class RecorderListAdapter : public AbstractAdapter { | ||
| 92 | +public: | ||
| 93 | + RecorderListAdapter(); | ||
| 94 | + ~RecorderListAdapter() override; | ||
| 95 | + uint16_t GetCount() override; | ||
| 96 | + UIView* GetView(UIView* inView, int16_t index) override; | ||
| 97 | + void Init(); | ||
| 98 | + void SetOnItemPlayListener(OnItemPlayListener* listener); | ||
| 99 | + void SetOnItemDeleteListener(OnItemDeleteListener* listener); | ||
| 100 | + void SetItems(std::vector<RecordItem>& items); | ||
| 101 | + void AddItem(const RecordItem& item); | ||
| 102 | + void RemoveItem(int16_t index); | ||
| 103 | + void UpdateItem(int16_t index, const RecordItem& item); | ||
| 104 | + bool GetItem(int16_t index, RecordItem& item) const; | ||
| 105 | +private: | ||
| 106 | + UIViewGroup* CreateItemView(); | ||
| 107 | + UIImageView* CreateFileIcon(); | ||
| 108 | + UILabel* CreateNameLabel(); | ||
| 109 | + UILabel* CreateTimeLabel(); | ||
| 110 | + UIImageView* CreatePlayButton(); | ||
| 111 | + UIImageView* CreateDeleteButton(); | ||
| 112 | + void BindItemView(UIViewGroup* root, int16_t index, RecordItem& item); | ||
| 113 | + void ResetItemListeners(UIImageView* playButton, UIImageView* deleteButton); | ||
| 114 | +private: | ||
| 115 | + std::vector<RecordItem> items_; | ||
| 116 | + char fileIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 117 | + char playIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 118 | + char pauseIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 119 | + char deleteIconAbsolutePath[MAX_PATH_LENGTH] = { 0 }; | ||
| 120 | + OnItemPlayListener* onItemPlayListener_ { nullptr }; | ||
| 121 | + OnItemDeleteListener* onItemDeleteListener_ { nullptr }; | ||
| 122 | +}; | ||
| 123 | + | ||
| 124 | +} | ||
| 125 | +#endif // OHOS_RECORDER_LIST_ADAPTER_H | ||
| @@ -0,0 +1,70 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef RECORDER_LOG_H | ||
| 17 | +#define RECORDER_LOG_H | ||
| 18 | + | ||
| 19 | +#ifdef HILOG_ENABLE | ||
| 20 | + | ||
| 21 | +#ifndef LOG_DOMAIN | ||
| 22 | +#define LOG_DOMAIN 0xD0000 | ||
| 23 | +#endif | ||
| 24 | + | ||
| 25 | +#ifndef LOG_TAG | ||
| 26 | +#define LOG_TAG "[RECORDER]" | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | +#include <hilog/log.h> | ||
| 30 | + | ||
| 31 | +#ifdef __cplusplus | ||
| 32 | +extern "C" { | ||
| 33 | +#endif | ||
| 34 | + | ||
| 35 | +#define FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__)) | ||
| 36 | + | ||
| 37 | +#define LOGD(fmt, ...) HILOG_DEBUG(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 38 | +#define LOGI(fmt, ...) HILOG_INFO(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 39 | +#define LOGW(fmt, ...) HILOG_WARN(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 40 | +#define LOGE(fmt, ...) HILOG_ERROR(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 41 | +#define LOGF(fmt, ...) HILOG_FATAL(LOG_APP, "[%s:%d] " fmt, FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 42 | + | ||
| 43 | +#ifdef __cplusplus | ||
| 44 | +} | ||
| 45 | +#endif | ||
| 46 | + | ||
| 47 | +#else | ||
| 48 | + | ||
| 49 | +#include <stdio.h> | ||
| 50 | +#include <string.h> | ||
| 51 | + | ||
| 52 | +#ifdef __cplusplus | ||
| 53 | +extern "C" { | ||
| 54 | +#endif | ||
| 55 | + | ||
| 56 | +#define FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__)) | ||
| 57 | + | ||
| 58 | +#define LOGD(fmt, ...) printf("[D][RECORDER][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 59 | +#define LOGI(fmt, ...) printf("[I][RECORDER][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 60 | +#define LOGW(fmt, ...) printf("[W][RECORDER][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 61 | +#define LOGE(fmt, ...) printf("[E][RECORDER][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 62 | +#define LOGF(fmt, ...) printf("[F][RECORDER][%s:%d] " fmt "\n", FILE_NAME, __LINE__, ##__VA_ARGS__) | ||
| 63 | + | ||
| 64 | +#ifdef __cplusplus | ||
| 65 | +} | ||
| 66 | +#endif | ||
| 67 | + | ||
| 68 | +#endif | ||
| 69 | + | ||
| 70 | +#endif /* RECORDER_LOG_H */ | ||
| @@ -0,0 +1,72 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_UTILS_H | ||
| 17 | +#define OHOS_RECORDER_UTILS_H | ||
| 18 | + | ||
| 19 | +#include <sstream> | ||
| 20 | +#include <iomanip> | ||
| 21 | +#include <ctime> | ||
| 22 | +#include <sys/stat.h> | ||
| 23 | + | ||
| 24 | +#include "recorder_config.h" | ||
| 25 | + | ||
| 26 | +namespace OHOS { | ||
| 27 | +const uint32_t MS_PER_SECOND = 1000; | ||
| 28 | +const long long MS_PER_MINUTE = 60 * MS_PER_SECOND; | ||
| 29 | +const long long MS_PER_HOUR = 60 * MS_PER_MINUTE; | ||
| 30 | + | ||
| 31 | +static std::string FormatDurationTime(uint32_t total_ms) | ||
| 32 | +{ | ||
| 33 | + if (total_ms == 0) { | ||
| 34 | + return "00:00:00"; | ||
| 35 | + } | ||
| 36 | + uint32_t hours = static_cast<uint32_t>(total_ms / MS_PER_HOUR); | ||
| 37 | + total_ms %= MS_PER_HOUR; | ||
| 38 | + uint32_t minutes = static_cast<uint32_t>(total_ms / MS_PER_MINUTE); | ||
| 39 | + total_ms %= MS_PER_MINUTE; | ||
| 40 | + uint32_t seconds = static_cast<uint32_t>(total_ms / MS_PER_SECOND); | ||
| 41 | + | ||
| 42 | + std::ostringstream oss; | ||
| 43 | + oss << std::setfill('0') | ||
| 44 | + << std::setw(TIME_FIELD_WIDTH) << hours | ||
| 45 | + << ":" | ||
| 46 | + << std::setw(TIME_FIELD_WIDTH) << minutes | ||
| 47 | + << ":" | ||
| 48 | + << std::setw(TIME_FIELD_WIDTH) << seconds; | ||
| 49 | + return oss.str(); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +static std::string FormatTime(long timeMs, const char* format) | ||
| 53 | +{ | ||
| 54 | + std::time_t time = timeMs; | ||
| 55 | + std::tm* tm = std::localtime(&time); | ||
| 56 | + std::stringstream ss; | ||
| 57 | + ss << std::put_time(tm, format); | ||
| 58 | + return ss.str(); | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +static long GetFileTime(const std::string& path) | ||
| 62 | +{ | ||
| 63 | + struct stat fileStat; | ||
| 64 | + if (stat(path.c_str(), &fileStat) == 0) { | ||
| 65 | + return fileStat.st_mtime; | ||
| 66 | + } else { | ||
| 67 | + LOGE("get file time failed, path:%s, errno:%d", path.c_str(), errno); | ||
| 68 | + return 0; | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | +} | ||
| 72 | +#endif // OHOS_RECORDER_ABILITY_H | ||
| @@ -0,0 +1,46 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef OHOS_RECORDER_TASK_HELPER_H | ||
| 17 | +#define OHOS_RECORDER_TASK_HELPER_H | ||
| 18 | + | ||
| 19 | +#include <sstream> | ||
| 20 | +#include <iomanip> | ||
| 21 | + | ||
| 22 | +#include <common/task_manager.h> | ||
| 23 | + | ||
| 24 | +namespace OHOS { | ||
| 25 | + | ||
| 26 | +template <typename Callable> | ||
| 27 | +class TaskLambdaWrapper : public Task { | ||
| 28 | +private: | ||
| 29 | + Callable m_func; | ||
| 30 | +public: | ||
| 31 | + explicit TaskLambdaWrapper(Callable func) : m_func(std::move(func)) {} | ||
| 32 | + | ||
| 33 | + void Callback() override | ||
| 34 | + { | ||
| 35 | + m_func(); | ||
| 36 | + } | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +template <typename Callable> | ||
| 40 | +static std::shared_ptr<Task> CreateTask(Callable func) | ||
| 41 | +{ | ||
| 42 | + return std::make_shared<TaskLambdaWrapper<Callable>>(std::move(func)); | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +} | ||
| 46 | +#endif // OHOS_RECORDER_TASK_HELPER_H | ||
| @@ -0,0 +1,464 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include <dirent.h> | ||
| 17 | +#include <fcntl.h> | ||
| 18 | +#include <cerrno> | ||
| 19 | +#include <cstdio> | ||
| 20 | +#include <sys/stat.h> | ||
| 21 | +#include <sys/types.h> | ||
| 22 | +#include <sstream> | ||
| 23 | + | ||
| 24 | +#include <media_errors.h> | ||
| 25 | + | ||
| 26 | +#include "recorder_ability.h" | ||
| 27 | +#include "recorder_log.h" | ||
| 28 | +#include "recorder_config.h" | ||
| 29 | +#include "media_utils.h" | ||
| 30 | + | ||
| 31 | +namespace OHOS { | ||
| 32 | +static constexpr size_t DATETIME_BUFFER_SIZE = 0x100; | ||
| 33 | +static constexpr mode_t RECORDER_DIRECTORY_MODE = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; | ||
| 34 | + | ||
| 35 | +static std::string GernerateFileName() | ||
| 36 | +{ | ||
| 37 | + time_t stCurrent; | ||
| 38 | + char aszDatetime[DATETIME_BUFFER_SIZE]; | ||
| 39 | + (void)time(&stCurrent); | ||
| 40 | + struct tm *pstCurrentTime = localtime(&(stCurrent)); | ||
| 41 | + if (pstCurrentTime == nullptr) { | ||
| 42 | + return ""; | ||
| 43 | + } | ||
| 44 | + if (strftime(aszDatetime, DATETIME_BUFFER_SIZE, RECORDER_FILE_NAME_FMT, pstCurrentTime) == 0) { | ||
| 45 | + return ""; | ||
| 46 | + } | ||
| 47 | + std::ostringstream oss; | ||
| 48 | + oss << RECORDER_DIRECTORY << aszDatetime << RECORDER_FILE_POSTFIX; | ||
| 49 | + return oss.str(); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +static bool IsDirExists(const char *path) | ||
| 53 | +{ | ||
| 54 | + struct stat st; | ||
| 55 | + int ret = lstat(path, &st); | ||
| 56 | + if (ret == -1) { | ||
| 57 | + if (errno == ENOENT) { | ||
| 58 | + return false; | ||
| 59 | + } | ||
| 60 | + perror("lstat failed"); | ||
| 61 | + exit(EXIT_FAILURE); | ||
| 62 | + } | ||
| 63 | + return S_ISDIR(st.st_mode); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +MediaUtils::~MediaUtils() | ||
| 67 | +{ | ||
| 68 | + CloseRecorder(); | ||
| 69 | + ClosePlayer(); | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +#ifdef USE_RECORDER_API | ||
| 73 | +class RecorderCallbackAdapter : public Media::RecorderCallback { | ||
| 74 | +public: | ||
| 75 | + RecorderCallbackAdapter(Media::RecorderCallback* from) | ||
| 76 | + { | ||
| 77 | + target = from; | ||
| 78 | + } | ||
| 79 | + ~RecorderCallbackAdapter() | ||
| 80 | + { | ||
| 81 | + target = nullptr; | ||
| 82 | + } | ||
| 83 | + void OnError(int32_t errorType, int32_t errorCode) override | ||
| 84 | + { | ||
| 85 | + if (target) { | ||
| 86 | + target->OnError(errorType, errorCode); | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + void OnInfo(int type, int extra) override | ||
| 90 | + { | ||
| 91 | + if (target) { | ||
| 92 | + target->OnError(type, extra); | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | +private: | ||
| 96 | + Media::RecorderCallback *target = nullptr; | ||
| 97 | +}; | ||
| 98 | + | ||
| 99 | +bool MediaUtils::SetRecorderCallback(Media::RecorderCallback* recorderCallback) | ||
| 100 | +{ | ||
| 101 | + recorderCallback_ = recorderCallback; | ||
| 102 | + return true; | ||
| 103 | +} | ||
| 104 | +#endif | ||
| 105 | + | ||
| 106 | +bool MediaUtils::InitRecorder() | ||
| 107 | +{ | ||
| 108 | + LOGI("InitRecorder"); | ||
| 109 | +#ifdef USE_RECORDER_API | ||
| 110 | + int32_t audioSourceId = 0; | ||
| 111 | + AudioSourceType inputSource = AUDIO_MIC; | ||
| 112 | + AudioCodecFormat audioFormat = AAC_LC; | ||
| 113 | + int32_t sampleRate = 48000; | ||
| 114 | + int32_t channelCount = 1; | ||
| 115 | + int32_t audioEncodingBitRate = 96000; | ||
| 116 | + | ||
| 117 | + recorder_ = std::make_shared<Media::Recorder>(); | ||
| 118 | + int ret = 0; | ||
| 119 | + | ||
| 120 | + if ((ret = recorder_->SetAudioSource(inputSource, audioSourceId)) != Media::SUCCESS) { | ||
| 121 | + LOGE("SetAudioSource failed, ret:%d", ret); | ||
| 122 | + return false; | ||
| 123 | + } | ||
| 124 | + if ((ret = recorder_->SetAudioEncoder(audioSourceId, audioFormat)) != Media::SUCCESS) { | ||
| 125 | + LOGE("SetAudioEncoder failed, ret:%d", ret); | ||
| 126 | + return false; | ||
| 127 | + } | ||
| 128 | + if ((ret = recorder_->SetAudioSampleRate(audioSourceId, sampleRate)) != Media::SUCCESS) { | ||
| 129 | + LOGE("SetAudioSampleRate failed, ret:%d", ret); | ||
| 130 | + return false; | ||
| 131 | + } | ||
| 132 | + if ((ret = recorder_->SetAudioChannels(audioSourceId, channelCount)) != Media::SUCCESS) { | ||
| 133 | + LOGE("SetAudioChannels failed, ret:%d", ret); | ||
| 134 | + return false; | ||
| 135 | + } | ||
| 136 | + if ((ret = recorder_->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate)) != Media::SUCCESS) { | ||
| 137 | + LOGE("SetAudioEncodingBitRate failed, ret:%d", ret); | ||
| 138 | + return false; | ||
| 139 | + } | ||
| 140 | + if ((ret = recorder_->SetMaxDuration(36000)) != Media::SUCCESS) { // 36000s=10h | ||
| 141 | + LOGE("SetMaxDuration failed, ret:%d", ret); | ||
| 142 | + return false; | ||
| 143 | + } | ||
| 144 | + if ((ret = recorder_->SetOutputFormat(Media::FORMAT_M4A)) != Media::SUCCESS) { | ||
| 145 | + LOGE("SetOutputFormat failed, ret:%d", ret); | ||
| 146 | + return false; | ||
| 147 | + } | ||
| 148 | + recorderCallbackPtr_ = std::make_shared<RecorderCallbackAdapter>(recorderCallback_); | ||
| 149 | + recorder_->SetRecorderCallback(recorderCallbackPtr_); | ||
| 150 | +#endif | ||
| 151 | + return true; | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +bool MediaUtils::StartRecord() | ||
| 155 | +{ | ||
| 156 | + LOGI("StartRecord"); | ||
| 157 | + if (recording_) { | ||
| 158 | + LOGW("already recording!"); | ||
| 159 | + return false; | ||
| 160 | + } | ||
| 161 | + if (!EnsureRecorderDirectory()) { | ||
| 162 | + return false; | ||
| 163 | + } | ||
| 164 | +#ifdef USE_RECORDER_FD | ||
| 165 | + std::string filename = GernerateFileName(); | ||
| 166 | + LOGI("GernerateFileName %s", filename.c_str()); | ||
| 167 | + recordFd_ = open(filename.c_str(), O_RDWR | O_CREAT); | ||
| 168 | + if (recordFd_ == -1) { | ||
| 169 | + LOGE("open file failed! filename:%s, errno:%d", filename.c_str(), errno); | ||
| 170 | + return false; | ||
| 171 | + } | ||
| 172 | +#endif | ||
| 173 | + if (!StartRecorderService()) { | ||
| 174 | + return false; | ||
| 175 | + } | ||
| 176 | + recording_ = true; | ||
| 177 | + return true; | ||
| 178 | +} | ||
| 179 | + | ||
| 180 | +bool MediaUtils::EnsureRecorderDirectory() | ||
| 181 | +{ | ||
| 182 | + if (IsDirExists(RECORDER_DIRECTORY)) { | ||
| 183 | + return true; | ||
| 184 | + } | ||
| 185 | + if (mkdir(RECORDER_DIRECTORY, RECORDER_DIRECTORY_MODE) != 0) { | ||
| 186 | + LOGE("mkdir for %s failed, errno:%d", RECORDER_DIRECTORY, errno); | ||
| 187 | + CloseRecorder(); | ||
| 188 | + return false; | ||
| 189 | + } | ||
| 190 | + return true; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +bool MediaUtils::StartRecorderService() | ||
| 194 | +{ | ||
| 195 | +#ifdef USE_RECORDER_API | ||
| 196 | + if (recorder_ == nullptr) { | ||
| 197 | + LOGW("recorder is nullptr, do init."); | ||
| 198 | + if (!InitRecorder()) { | ||
| 199 | + LOGE("recorder init failed!"); | ||
| 200 | + return false; | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + int ret = 0; | ||
| 205 | +#if USE_RECORDER_FD | ||
| 206 | + if ((ret = recorder_->SetOutputFile(recordFd_)) != Media::SUCCESS) { | ||
| 207 | + LOGE("SetOutputPath failed. ret:%d", ret); | ||
| 208 | + CloseRecorder(); | ||
| 209 | + return false; | ||
| 210 | + } | ||
| 211 | +#else | ||
| 212 | + if ((ret = recorder_->SetOutputPath(RECORDER_DIRECTORY)) != Media::SUCCESS) { | ||
| 213 | + LOGE("SetOutputPath failed. ret:%d", ret); | ||
| 214 | + CloseRecorder(); | ||
| 215 | + return false; | ||
| 216 | + } | ||
| 217 | +#endif | ||
| 218 | + | ||
| 219 | + ret = recorder_->Prepare(); | ||
| 220 | + if (ret != Media::SUCCESS) { | ||
| 221 | + LOGE("Prepare failed. ret:%d", ret); | ||
| 222 | + CloseRecorder(); | ||
| 223 | + return false; | ||
| 224 | + } | ||
| 225 | + ret = recorder_->Start(); | ||
| 226 | + if (ret != Media::SUCCESS) { | ||
| 227 | + LOGE("Start failed. ret:%d", ret); | ||
| 228 | + CloseRecorder(); | ||
| 229 | + return false; | ||
| 230 | + } | ||
| 231 | +#endif | ||
| 232 | + return true; | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +bool MediaUtils::StopRecord() | ||
| 236 | +{ | ||
| 237 | + LOGI("StopRecord"); | ||
| 238 | + if (!recording_) { | ||
| 239 | + LOGW("current not recording!"); | ||
| 240 | + return false; | ||
| 241 | + } | ||
| 242 | + CloseRecorder(); | ||
| 243 | + MoveFiles(); | ||
| 244 | + recording_ = false; | ||
| 245 | + return true; | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +bool MediaUtils::MoveFiles() | ||
| 249 | +{ | ||
| 250 | + LOGI("MoveFiles"); | ||
| 251 | + struct dirent* entry; | ||
| 252 | + DIR* dir = opendir(RECORDER_TEMP_DIRECTORY); | ||
| 253 | + if (dir == nullptr) { | ||
| 254 | + LOGE("open recorder dir failed. errno:%d", errno); | ||
| 255 | + return false; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + while ((entry = readdir(dir)) != nullptr) { | ||
| 259 | + std::string filename = entry->d_name; | ||
| 260 | + if (entry->d_type == DT_REG && | ||
| 261 | + filename.size() > RECORDER_FILE_POSTFIX_LENGTH && | ||
| 262 | + (filename.substr(filename.size() - RECORDER_FILE_POSTFIX_LENGTH) == RECORDER_TEMP_FILE_POSTFIX)) { | ||
| 263 | + LOGI("find file: %s", filename.c_str()); | ||
| 264 | + std::string src = std::string(RECORDER_TEMP_DIRECTORY) + filename; | ||
| 265 | + std::string dst = std::string(RECORDER_DIRECTORY) + | ||
| 266 | + filename.substr(0, filename.size() - RECORDER_FILE_POSTFIX_LENGTH) + | ||
| 267 | + RECORDER_FILE_POSTFIX; | ||
| 268 | + if (rename(src.c_str(), dst.c_str()) != 0) { | ||
| 269 | + LOGE("rename file failed, errno:%d, src:%s, dst:%s", errno, src.c_str(), dst.c_str()); | ||
| 270 | + continue; | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + closedir(dir); | ||
| 275 | + return true; | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +bool MediaUtils::CloseRecorder() | ||
| 279 | +{ | ||
| 280 | + LOGI("CloseRecorder"); | ||
| 281 | +#ifdef USE_RECORDER_API | ||
| 282 | + if (recorder_) { | ||
| 283 | + recorder_->Stop(true); | ||
| 284 | + recorder_->Release(); | ||
| 285 | + recorder_ = nullptr; | ||
| 286 | + } | ||
| 287 | +#endif | ||
| 288 | + | ||
| 289 | +#ifdef USE_RECORDER_FD | ||
| 290 | + if (recordFd_ != -1) { | ||
| 291 | + FILE *fp = fdopen(recordFd_, "w+"); | ||
| 292 | + if (fp) { | ||
| 293 | + fflush(fp); | ||
| 294 | + fsync(recordFd_); | ||
| 295 | + fclose(fp); | ||
| 296 | + close(recordFd_); | ||
| 297 | + } | ||
| 298 | + recordFd_ = -1; | ||
| 299 | + } | ||
| 300 | +#endif | ||
| 301 | + return true; | ||
| 302 | +} | ||
| 303 | + | ||
| 304 | +// Player | ||
| 305 | +#ifdef USE_PLAYER_API | ||
| 306 | +class PlayerCallbackAdapter : public Media::PlayerCallback { | ||
| 307 | +public: | ||
| 308 | + PlayerCallbackAdapter(Media::PlayerCallback* from) | ||
| 309 | + { | ||
| 310 | + target = from; | ||
| 311 | + } | ||
| 312 | + ~PlayerCallbackAdapter() override | ||
| 313 | + { | ||
| 314 | + target = nullptr; | ||
| 315 | + } | ||
| 316 | + void OnPlaybackComplete() override | ||
| 317 | + { | ||
| 318 | + if (target) { | ||
| 319 | + target->OnPlaybackComplete(); | ||
| 320 | + } | ||
| 321 | + } | ||
| 322 | + void OnError(int32_t errorType, int32_t errorCode) override | ||
| 323 | + { | ||
| 324 | + if (target) { | ||
| 325 | + target->OnError(errorType, errorCode); | ||
| 326 | + } | ||
| 327 | + } | ||
| 328 | + void OnInfo(int type, int extra) override | ||
| 329 | + { | ||
| 330 | + if (target) { | ||
| 331 | + target->OnError(type, extra); | ||
| 332 | + } | ||
| 333 | + } | ||
| 334 | + void OnVideoSizeChanged(int width, int height) override | ||
| 335 | + { | ||
| 336 | + if (target) { | ||
| 337 | + target->OnVideoSizeChanged(width, height); | ||
| 338 | + } | ||
| 339 | + } | ||
| 340 | + void OnRewindToComplete() override | ||
| 341 | + { | ||
| 342 | + if (target) { | ||
| 343 | + target->OnRewindToComplete(); | ||
| 344 | + } | ||
| 345 | + } | ||
| 346 | +private: | ||
| 347 | + Media::PlayerCallback *target = nullptr; | ||
| 348 | +}; | ||
| 349 | + | ||
| 350 | +bool MediaUtils::SetPlayerCallback(Media::PlayerCallback* playerCallback) | ||
| 351 | +{ | ||
| 352 | + playerCallback_ = playerCallback; | ||
| 353 | + return true; | ||
| 354 | +} | ||
| 355 | +#endif | ||
| 356 | + | ||
| 357 | +bool MediaUtils::InitPlayer(const char* filePath) | ||
| 358 | +{ | ||
| 359 | + LOGI("InitPlayer"); | ||
| 360 | +#ifdef USE_PLAYER_API | ||
| 361 | + player_ = std::make_shared<Media::Player>(); | ||
| 362 | + if (!player_) { | ||
| 363 | + LOGE("create Player failed!"); | ||
| 364 | + return false; | ||
| 365 | + } | ||
| 366 | + std::string uri(filePath); | ||
| 367 | + Media::Source source(uri); | ||
| 368 | + int ret = player_->SetSource(source); | ||
| 369 | + if (ret != Media::SUCCESS) { | ||
| 370 | + LOGE("SetSource failed!"); | ||
| 371 | + ClosePlayer(); | ||
| 372 | + return false; | ||
| 373 | + } | ||
| 374 | + playerCallbackPtr_ = std::make_shared<PlayerCallbackAdapter>(playerCallback_); | ||
| 375 | + player_->SetPlayerCallback(playerCallbackPtr_); | ||
| 376 | +#endif | ||
| 377 | + return true; | ||
| 378 | +} | ||
| 379 | + | ||
| 380 | +bool MediaUtils::StartPlay(const char* filePath) | ||
| 381 | +{ | ||
| 382 | + LOGI("StartPlay file:%s", filePath); | ||
| 383 | + if (playing_ && !paused_) { | ||
| 384 | + LOGW("already playing."); | ||
| 385 | + return false; | ||
| 386 | + } | ||
| 387 | +#ifdef USE_PLAYER_API | ||
| 388 | + if (!player_) { | ||
| 389 | + LOGE("player is null, do init!"); | ||
| 390 | + if (!InitPlayer(filePath)) { | ||
| 391 | + LOGE("init player failed"); | ||
| 392 | + return false; | ||
| 393 | + } | ||
| 394 | + } | ||
| 395 | + int ret = 0; | ||
| 396 | + if (playing_ && paused_) { | ||
| 397 | + ret = player_->Play(); | ||
| 398 | + if (ret != Media::SUCCESS) { | ||
| 399 | + LOGE("Play(resume) failed!"); | ||
| 400 | + ClosePlayer(); | ||
| 401 | + return false; | ||
| 402 | + } | ||
| 403 | + } else { | ||
| 404 | + ret = player_->Prepare(); | ||
| 405 | + if (ret != Media::SUCCESS) { | ||
| 406 | + LOGE("Prepare failed!"); | ||
| 407 | + ClosePlayer(); | ||
| 408 | + return false; | ||
| 409 | + } | ||
| 410 | + ret = player_->Play(); | ||
| 411 | + if (ret != Media::SUCCESS) { | ||
| 412 | + LOGE("Play failed!"); | ||
| 413 | + ClosePlayer(); | ||
| 414 | + return false; | ||
| 415 | + } | ||
| 416 | + } | ||
| 417 | +#endif | ||
| 418 | + playing_ = true; | ||
| 419 | + paused_ = false; | ||
| 420 | + return true; | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +bool MediaUtils::PausePlay() | ||
| 424 | +{ | ||
| 425 | + LOGI("PausePlay"); | ||
| 426 | +#ifdef USE_PLAYER_API | ||
| 427 | + int ret = player_->Pause(); | ||
| 428 | + if (ret != Media::SUCCESS) { | ||
| 429 | + LOGE("Pause failed!"); | ||
| 430 | + ClosePlayer(); | ||
| 431 | + return false; | ||
| 432 | + } | ||
| 433 | +#endif | ||
| 434 | + paused_ = true; | ||
| 435 | + return true; | ||
| 436 | +} | ||
| 437 | + | ||
| 438 | +bool MediaUtils::StopPlay() | ||
| 439 | +{ | ||
| 440 | + LOGI("StopPlay"); | ||
| 441 | + if (!playing_) { | ||
| 442 | + LOGW("current not playing!"); | ||
| 443 | + return false; | ||
| 444 | + } | ||
| 445 | + ClosePlayer(); | ||
| 446 | + return true; | ||
| 447 | +} | ||
| 448 | + | ||
| 449 | +bool MediaUtils::ClosePlayer() | ||
| 450 | +{ | ||
| 451 | + LOGI("ClosePlayer"); | ||
| 452 | +#ifdef USE_PLAYER_API | ||
| 453 | + if (player_) { | ||
| 454 | + player_->Stop(); | ||
| 455 | + player_->Release(); | ||
| 456 | + player_ = nullptr; | ||
| 457 | + } | ||
| 458 | +#endif | ||
| 459 | + playing_ = false; | ||
| 460 | + paused_ = false; | ||
| 461 | + return true; | ||
| 462 | +} | ||
| 463 | + | ||
| 464 | +} | ||
| @@ -0,0 +1,53 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include "recorder_ability.h" | ||
| 17 | +#include "recorder_log.h" | ||
| 18 | + | ||
| 19 | +namespace OHOS { | ||
| 20 | +REGISTER_AA(RecorderAbility) | ||
| 21 | + | ||
| 22 | +void RecorderAbility::OnStart(const Want &want) | ||
| 23 | +{ | ||
| 24 | + LOGI("Recorder::OnStart"); | ||
| 25 | + SetMainRoute("RecorderAbilityMainSlice"); | ||
| 26 | + | ||
| 27 | + Ability::OnStart(want); | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +void RecorderAbility::OnInactive() | ||
| 31 | +{ | ||
| 32 | + LOGI("Recorder::OnInactive"); | ||
| 33 | + Ability::OnInactive(); | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +void RecorderAbility::OnActive(const Want &want) | ||
| 37 | +{ | ||
| 38 | + LOGI("Recorder::OnActive"); | ||
| 39 | + Ability::OnActive(want); | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +void RecorderAbility::OnBackground() | ||
| 43 | +{ | ||
| 44 | + LOGI("Recorder::OnBackground"); | ||
| 45 | + Ability::OnBackground(); | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +void RecorderAbility::OnStop() | ||
| 49 | +{ | ||
| 50 | + LOGI("Recorder::OnStop"); | ||
| 51 | + Ability::OnStop(); | ||
| 52 | +} | ||
| 53 | +} | ||
| @@ -0,0 +1,585 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 RKH Corp. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#include <ability_env.h> | ||
| 17 | +#include <ability_loader.h> | ||
| 18 | +#include <ability_manager.h> | ||
| 19 | +#include <components/text_adapter.h> | ||
| 20 | +#include <common/screen.h> | ||
| 21 | +#include <hal_tick.h> | ||
| 22 | + | ||
| 23 | +#include <dirent.h> | ||
| 24 | +#include <algorithm> | ||
| 25 | +#include <cstdio> | ||
| 26 | + | ||
| 27 | +#include "recorder_ability_main_slice.h" | ||
| 28 | +#include "recorder_log.h" | ||
| 29 | +#include "recorder_utils.h" | ||
| 30 | + | ||
| 31 | +namespace OHOS { | ||
| 32 | +REGISTER_AS(RecorderAbilityMainSlice) | ||
| 33 | + | ||
| 34 | +static constexpr uint8_t NOTICE_COLOR_RED = 78; | ||
| 35 | +static constexpr uint8_t NOTICE_COLOR_GREEN = 89; | ||
| 36 | +static constexpr uint8_t NOTICE_COLOR_BLUE = 105; | ||
| 37 | +static constexpr uint8_t ROOT_COLOR_RED = 249; | ||
| 38 | +static constexpr uint8_t ROOT_COLOR_GREEN = 250; | ||
| 39 | +static constexpr uint8_t ROOT_COLOR_BLUE = 251; | ||
| 40 | + | ||
| 41 | +RecorderAbilityMainSlice::~RecorderAbilityMainSlice() | ||
| 42 | +{ | ||
| 43 | + LOGI("~RecorderAbilityMainSlice()"); | ||
| 44 | + StopTimer(); | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +void RecorderAbilityMainSlice::InitTitle() | ||
| 48 | +{ | ||
| 49 | + LOGI("RecorderAbilityMainSlice::InitTitle"); | ||
| 50 | + titleBar_ = new UIViewGroup(); | ||
| 51 | + titleBar_->SetPosition(TITLE_BAR_X, TITLE_BAR_Y, TITLE_BAR_WIDTH, TITLE_BAR_HEIGHT); | ||
| 52 | + titleBar_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); | ||
| 53 | + titleBar_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); | ||
| 54 | + | ||
| 55 | + backButton_ = new UIImageView(); | ||
| 56 | + backButton_->SetPosition(BACK_ICON_X, BACK_ICON_Y, BACK_ICON_WIDTH, BACK_ICON_HEIGHT); | ||
| 57 | + backButton_->SetStyle(STYLE_PADDING_LEFT, BACK_ICON_PADDING_H); | ||
| 58 | + backButton_->SetStyle(STYLE_PADDING_RIGHT, BACK_ICON_PADDING_H); | ||
| 59 | + backButton_->SetStyle(STYLE_PADDING_TOP, BACK_ICON_PADDING_V); | ||
| 60 | + backButton_->SetStyle(STYLE_PADDING_BOTTOM, BACK_ICON_PADDING_V); | ||
| 61 | + backButton_->SetSrc(backIconAbsolutePath); | ||
| 62 | + backButton_->SetTouchable(true); | ||
| 63 | + | ||
| 64 | + auto onClick = [this] (UIView& view, const Event& event) -> bool { | ||
| 65 | + LOGI("TerminateAbility by BackPress"); | ||
| 66 | + TerminateAbility(); | ||
| 67 | + return true; | ||
| 68 | + }; | ||
| 69 | + backButtonListener_ = new EventListener(onClick, nullptr); | ||
| 70 | + backButton_->SetOnClickListener(backButtonListener_); | ||
| 71 | + | ||
| 72 | + titleLabel_ = new UILabel(); | ||
| 73 | + titleLabel_->SetPosition(TITLE_LABEL_X, TITLE_LABEL_Y, TITLE_LABEL_WIDTH, TITLE_LABEL_HEIGHT); | ||
| 74 | + titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | ||
| 75 | + titleLabel_->SetFont(FONT_NAME, TITLE_LABEL_FONT_SIZE); | ||
| 76 | + titleLabel_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); | ||
| 77 | + titleLabel_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); | ||
| 78 | + titleLabel_->SetText("录音机"); | ||
| 79 | + | ||
| 80 | + titleBar_->Add(backButton_); | ||
| 81 | + titleBar_->Add(titleLabel_); | ||
| 82 | + rootView_->Add(titleBar_); | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +void RecorderAbilityMainSlice::InitRecordCtrl() | ||
| 86 | +{ | ||
| 87 | + InitRecordLabels(); | ||
| 88 | + InitRecordButtons(); | ||
| 89 | + InitRecordListeners(); | ||
| 90 | + AddRecordControlsToRoot(); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +void RecorderAbilityMainSlice::InitRecordLabels() | ||
| 94 | +{ | ||
| 95 | + noticeLabel_ = new UILabel(); | ||
| 96 | + noticeLabel_->SetPosition(NOTICE_LABEL_X, NOTICE_LABEL_Y, NOTICE_LABEL_WIDTH, NOTICE_LABEL_HEIGHT); | ||
| 97 | + noticeLabel_->SetAlign( | ||
| 98 | + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, | ||
| 99 | + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); | ||
| 100 | + noticeLabel_->SetFont(FONT_NAME, NOTICE_LABEL_FONT_SIZE); | ||