1 /*
2 * Copyright (c) 2021 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
16 #include "core/components/video/resource/resource.h"
17
18 #include <sstream>
19
20 #include "base/log/log.h"
21
22 namespace OHOS::Ace {
23
24 const char PARAM_NONE[] = "";
25 const char PARAM_AND[] = "#HWJS-&-#";
26 const char PARAM_VALUE[] = "value";
27 const char PARAM_EQUALS[] = "#HWJS-=-#";
28 const char PARAM_BEGIN[] = "#HWJS-?-#";
29 const char METHOD[] = "method";
30 const char EVENT[] = "event";
31 const char RESULT_FAIL[] = "fail";
32
Release(const std::function<void (bool)> & onRelease)33 void Resource::Release(const std::function<void(bool)>& onRelease)
34 {
35 if (id_ == INVALID_ID) {
36 return;
37 }
38
39 auto context = context_.Upgrade();
40 if (!context) {
41 LOGE("fail to release resource due to context is null");
42 return;
43 }
44
45 auto resRegister = context->GetPlatformResRegister();
46 auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
47 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
48 auto releaseTask = [weak = AceType::WeakClaim(this), weakRes, onRelease] {
49 auto resource = weak.Upgrade();
50 auto resRegister = weakRes.Upgrade();
51 if (resource == nullptr || resRegister == nullptr) {
52 LOGE("resource or resRegister is nullptr");
53 return;
54 }
55 bool ret = resRegister->ReleaseResource(resource->hash_);
56 if (ret) {
57 resource->id_ = INVALID_ID;
58 resource->hash_.clear();
59 }
60 if (onRelease) {
61 onRelease(ret);
62 }
63 };
64 if (platformTaskExecutor.IsRunOnCurrentThread()) {
65 releaseTask();
66 } else {
67 platformTaskExecutor.PostTask(releaseTask, "ArkUIVideoResourceRelease");
68 }
69 }
70
GetDoubleParam(const std::string & param,const std::string & name) const71 double Resource::GetDoubleParam(const std::string& param, const std::string& name) const
72 {
73 size_t len = name.length();
74 size_t pos = param.find(name);
75 double result = 0.0;
76
77 if (pos != std::string::npos) {
78 std::stringstream ss;
79
80 ss << param.substr(pos + 1 + len);
81 ss >> result;
82 }
83
84 return result;
85 }
86
GetIntParam(const std::string & param,const std::string & name) const87 int32_t Resource::GetIntParam(const std::string& param, const std::string& name) const
88 {
89 size_t len = name.length();
90 size_t pos = param.find(name);
91 int32_t result = 0;
92
93 if (pos != std::string::npos) {
94 std::stringstream ss;
95
96 ss << param.substr(pos + 1 + len);
97 ss >> result;
98 }
99
100 return result;
101 }
102
GetInt64Param(const std::string & param,const std::string & name) const103 int64_t Resource::GetInt64Param(const std::string& param, const std::string& name) const
104 {
105 size_t len = name.length();
106 size_t pos = param.find(name);
107 int64_t result = 0;
108
109 if (pos != std::string::npos) {
110 std::stringstream ss;
111 ss << param.substr(pos + 1 + len);
112 ss >> result;
113 }
114
115 return result;
116 }
117
GetFloatArrayParam(const std::string & param,const std::string & name,std::vector<float> & matrix) const118 void Resource::GetFloatArrayParam(const std::string& param, const std::string& name, std::vector<float>& matrix) const
119 {
120 size_t len = name.length();
121 size_t pos = param.find(name);
122 matrix.clear();
123 if (pos == std::string::npos) {
124 return;
125 }
126 std::string data = param.substr(pos + 1 + len);
127 pos = data.find("[");
128 if (pos == std::string::npos) {
129 return;
130 }
131 do {
132 std::stringstream ss;
133 ss << data.substr(pos + 1);
134 float tmp = 0;
135 ss >> tmp;
136 matrix.emplace_back(tmp);
137 data = data.substr(pos + 1);
138 pos = data.find(",");
139 if (pos == std::string::npos) {
140 return;
141 }
142 } while (1);
143 return;
144 }
145
ParseMapFromString(const std::string & param)146 std::map<std::string, std::string> Resource::ParseMapFromString(const std::string& param)
147 {
148 size_t equalsLen = sizeof(PARAM_EQUALS) - 1;
149 size_t andLen = sizeof(PARAM_EQUALS) - 1;
150 size_t totalLen = param.length();
151 size_t index = 0;
152 std::map<std::string, std::string> result;
153 while (index < totalLen) {
154 size_t end = param.find(PARAM_AND, index);
155 if (end == std::string::npos) {
156 end = totalLen;
157 }
158
159 size_t mid = param.find(PARAM_EQUALS, index);
160 if (mid == std::string::npos) {
161 index = end + andLen;
162 continue;
163 }
164 std::string key = param.substr(index, mid - index);
165 std::string value = param.substr(mid + equalsLen, end - mid - equalsLen);
166 result[key] = value;
167 index = end + andLen;
168 }
169 return result;
170 }
171
MakeResourceHash() const172 std::string Resource::MakeResourceHash() const
173 {
174 std::stringstream hashCode;
175 hashCode << type_ << "@" << id_;
176
177 return hashCode.str();
178 }
179
MakeEventHash(const std::string & event) const180 std::string Resource::MakeEventHash(const std::string& event) const
181 {
182 std::string eventHash = hash_;
183
184 eventHash += std::string(EVENT);
185 eventHash += std::string(PARAM_EQUALS);
186 eventHash += event;
187 eventHash += std::string(PARAM_BEGIN);
188
189 return eventHash;
190 }
191
MakeMethodHash(const std::string & method) const192 std::string Resource::MakeMethodHash(const std::string& method) const
193 {
194 std::string methodHash = hash_;
195
196 methodHash += std::string(METHOD);
197 methodHash += std::string(PARAM_EQUALS);
198 methodHash += method;
199 methodHash += std::string(PARAM_BEGIN);
200
201 return methodHash;
202 }
203
IsResultSuccess(const std::string & result) const204 bool Resource::IsResultSuccess(const std::string& result) const
205 {
206 size_t pos = result.find(RESULT_FAIL);
207
208 return pos != 0;
209 }
210
OnError(const std::string & errorCode,const std::string & errorMsg)211 void Resource::OnError(const std::string& errorCode, const std::string& errorMsg)
212 {
213 if (onError_) {
214 onError_(errorCode, errorMsg);
215 }
216 }
217
CallResRegisterMethod(const std::string & method,const std::string & param,const std::function<void (std::string &)> & callback)218 void Resource::CallResRegisterMethod(
219 const std::string& method, const std::string& param, const std::function<void(std::string&)>& callback)
220 {
221 if (method.empty()) {
222 return;
223 }
224
225 auto context = context_.Upgrade();
226 if (!context) {
227 LOGE("fail to get context to call res register method");
228 return;
229 }
230
231 auto resRegister = context->GetPlatformResRegister();
232 auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
233 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
234 platformTaskExecutor.PostTask([method, param, weakRes, callback] {
235 auto resRegister = weakRes.Upgrade();
236 if (resRegister == nullptr) {
237 LOGE("resRegister is nullptr");
238 return;
239 }
240 std::string result;
241 resRegister->OnMethodCall(method, param, result);
242 if (callback) {
243 callback(result);
244 }
245 }, "ArkUIVideoCallResRegisterMethod");
246 }
247
CallSyncResRegisterMethod(const Method & method,const std::string & param,const std::function<void (std::string &)> & callback)248 void Resource::CallSyncResRegisterMethod(
249 const Method& method, const std::string& param, const std::function<void(std::string&)>& callback)
250 {
251 if (method.empty()) {
252 return;
253 }
254
255 auto context = context_.Upgrade();
256 if (!context) {
257 LOGE("fail to get context to call res register method");
258 return;
259 }
260
261 auto resRegister = context->GetPlatformResRegister();
262 std::string result;
263 if (!resRegister) {
264 LOGE("fail to get resRegister to call res register method");
265 return;
266 }
267 resRegister->OnMethodCall(method, param, result);
268 if (callback) {
269 callback(result);
270 }
271 }
272
273 } // namespace OHOS::Ace