1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
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 #include "loader_callback_mock.h"
16 #include "media_log.h"
17 #include "media_errors.h"
18
19 namespace {
20 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "MockLoaderCallback" };
21 constexpr int32_t LOADING_ERROR_NO_RESOURCE = 2;
22 static std::atomic<int64_t> g_uuid = 1;
23 static const std::map<std::string, std::string> g_urlToLocalPath = {
24 {"https://appimg.dbankcdn.com/appVideo/f59583660abd45bcb4fb9c3e3f1125a9.mp4", "/data/test/request.mp4"},
25 };
26 static const std::map<std::string, std::map<std::string, std::string>> g_urlToHeader = {
27 {"https://appimg.dbankcdn.com/appVideo/f59583660abd45bcb4fb9c3e3f1125a9.mp4", {{"content-length", "9924003"}}},
28 };
29 }
30
31 namespace OHOS {
32 namespace Media {
MockLoaderCallback()33 MockLoaderCallback::MockLoaderCallback()
34 : taskQue_("MockLoaderCallback")
35 {
36 MEDIA_LOGD("MockLoaderCallback:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
37 (void)taskQue_.Start();
38 }
39
~MockLoaderCallback()40 MockLoaderCallback::~MockLoaderCallback()
41 {
42 if (file_ != nullptr) {
43 (void)fclose(file_);
44 file_ = nullptr;
45 }
46 (void)taskQue_.Stop();
47 MEDIA_LOGD("MockLoaderCallback:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
48 }
49
Open(std::shared_ptr<LoadingRequest> & request)50 int64_t MockLoaderCallback::Open(std::shared_ptr<LoadingRequest> &request)
51 {
52 MEDIA_LOGI("Open enter");
53 int64_t uuid = g_uuid.fetch_add(1, std::memory_order_relaxed);
54 requests_[uuid] = request;
55 auto localPath = g_urlToLocalPath.find(request->GetUrl());
56 if (localPath != g_urlToLocalPath.end()) {
57 if (file_ != nullptr) {
58 fclose(file_);
59 file_ = nullptr;
60 }
61 file_ = fopen(localPath->second.c_str(), "rb+");
62 }
63 return uuid;
64 }
65
Read(int64_t uuid,int64_t requestedOffset,int64_t requestedLength)66 void MockLoaderCallback::Read(int64_t uuid, int64_t requestedOffset, int64_t requestedLength)
67 {
68 MEDIA_LOGI("Read enter");
69 auto request = requests_.find(uuid);
70 if (request != requests_.end()) {
71 // respond header
72 auto task = std::make_shared<TaskHandler<void>>([=] {
73 MEDIA_LOGI("task RespondHeader enter");
74 auto header = g_urlToHeader.find(request->second->GetUrl());
75 if (header == g_urlToHeader.end()) {
76 MEDIA_LOGI("get header fail");
77 (void)request->second->FinishLoading(uuid, LOADING_ERROR_NO_RESOURCE);
78 return;
79 }
80 (void)request->second->RespondHeader(uuid, header->second, "");
81 });
82 (void)taskQue_.EnqueueTask(task);
83 // respond data
84 task = std::make_shared<TaskHandler<void>>([=] {
85 MEDIA_LOGI("task RespondData enter");
86 auto buffer = std::make_shared<AVSharedMemoryBase>(static_cast<int32_t>(requestedLength),
87 AVSharedMemory::FLAGS_READ_WRITE, "userBuffer");
88 if (buffer == nullptr || file_ == nullptr) {
89 MEDIA_LOGI("get buffer fail");
90 (void)request->second->FinishLoading(uuid, LOADING_ERROR_NO_RESOURCE);
91 return;
92 }
93 buffer->Init();
94 (void)fseek(file_, static_cast<long>(requestedOffset), SEEK_SET);
95 size_t readRet = fread(buffer->GetBase(), static_cast<size_t>(requestedLength), 1, file_);
96 if (ferror(file_) || readRet != 1) {
97 MEDIA_LOGE("IO error, offest %{public}" PRId64 " length %{public}" PRId64 "readRet %{public}d",
98 requestedOffset, requestedLength, static_cast<int32_t>(readRet));
99 (void)request->second->FinishLoading(uuid, LOADING_ERROR_NO_RESOURCE);
100 return;
101 }
102 (void)request->second->RespondData(uuid, requestedOffset, buffer);
103 });
104 (void)taskQue_.EnqueueTask(task);
105 } else {
106 MEDIA_LOGI("read uuid fail");
107 }
108 }
109
Close(int64_t uuid)110 void MockLoaderCallback::Close(int64_t uuid)
111 {
112 MEDIA_LOGI("Close enter");
113 requests_.erase(uuid);
114 if (file_ != nullptr) {
115 fclose(file_);
116 file_ = nullptr;
117 }
118 }
119 } // namespace Media
120 } // namespace OHOS