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/rich_text/resource/rich_text_resource.h"
17 
18 #include <sstream>
19 
20 #include "base/log/log.h"
21 
22 namespace OHOS::Ace {
23 
24 const char RICHTEXT_PARAM_NONE[] = "";
25 const char RICHTEXT_PARAM_AND[] = "#HWJS-&-#";
26 const char RICHTEXT_PARAM_VALUE[] = "value";
27 const char RICHTEXT_PARAM_EQUALS[] = "#HWJS-=-#";
28 const char RICHTEXT_PARAM_BEGIN[] = "#HWJS-?-#";
29 const char RICHTEXT_METHOD[] = "method";
30 const char RICHTEXT_EVENT[] = "event";
31 const char RICHTEXT_RESULT_FAIL[] = "fail";
32 
Release(const std::function<void (bool)> & onRelease)33 void RichTextResource::Release(const std::function<void(bool)>& onRelease)
34 {
35     auto context = context_.Upgrade();
36     if (!context) {
37         LOGE("fail to release resource due to context is null");
38         return;
39     }
40 
41     auto resRegister = context->GetPlatformResRegister();
42     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(),
43                                                          TaskExecutor::TaskType::PLATFORM);
44     auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
45     auto releaseTask = [weak = WeakClaim(this), weakRes, onRelease] {
46         auto resource = weak.Upgrade();
47         if (!resource || resource->id_ == INVALID_ID) {
48             LOGW("rich text resource has released");
49             return;
50         }
51 
52         auto resRegister = weakRes.Upgrade();
53         if (resRegister) {
54             bool ret = resRegister->ReleaseResource(resource->GetHashCode());
55             if (ret) {
56                 resource->Reset();
57             }
58             if (onRelease) {
59                 onRelease(ret);
60             }
61         }
62     };
63     if (platformTaskExecutor.IsRunOnCurrentThread()) {
64         releaseTask();
65     } else {
66         platformTaskExecutor.PostTask(releaseTask, "ArkUIRichTextResourceRelease");
67     }
68 }
69 
GetDoubleParam(const std::string & param,const std::string & name) const70 double RichTextResource::GetDoubleParam(const std::string& param, const std::string& name) const
71 {
72     size_t len = name.length();
73     size_t pos = param.find(name);
74     double result = 0.0;
75 
76     if (pos != std::string::npos) {
77         std::stringstream ss;
78 
79         ss << param.substr(pos + 1 + len);
80         ss >> result;
81     }
82 
83     return result;
84 }
85 
GetIntParam(const std::string & param,const std::string & name) const86 int32_t RichTextResource::GetIntParam(const std::string& param, const std::string& name) const
87 {
88     size_t len = name.length();
89     size_t pos = param.find(name);
90     int32_t result = 0;
91 
92     if (pos != std::string::npos) {
93         std::stringstream ss;
94 
95         ss << param.substr(pos + 1 + len);
96         ss >> result;
97     }
98 
99     return result;
100 }
101 
MakeResourceHash() const102 std::string RichTextResource::MakeResourceHash() const
103 {
104     std::stringstream hashCode;
105     hashCode << type_ << "@" << id_;
106 
107     return hashCode.str();
108 }
109 
MakeEventHash(const std::string & event) const110 std::string RichTextResource::MakeEventHash(const std::string& event) const
111 {
112     std::string eventHash = hash_;
113 
114     eventHash += std::string(RICHTEXT_EVENT);
115     eventHash += std::string(RICHTEXT_PARAM_EQUALS);
116     eventHash += event;
117     eventHash += std::string(RICHTEXT_PARAM_BEGIN);
118 
119     return eventHash;
120 }
121 
MakeMethodHash(const std::string & method) const122 std::string RichTextResource::MakeMethodHash(const std::string& method) const
123 {
124     std::string methodHash = hash_;
125 
126     methodHash += std::string(RICHTEXT_METHOD);
127     methodHash += std::string(RICHTEXT_PARAM_EQUALS);
128     methodHash += method;
129     methodHash += std::string(RICHTEXT_PARAM_BEGIN);
130 
131     return methodHash;
132 }
133 
OnError(const std::string & errorCode,const std::string & errorMsg)134 void RichTextResource::OnError(const std::string& errorCode, const std::string& errorMsg)
135 {
136     if (onError_) {
137         onError_(errorCode, errorMsg);
138     }
139 }
140 
CallResRegisterMethod(const std::string & method,const std::string & param,const std::function<void (std::string &)> & callback)141 void RichTextResource::CallResRegisterMethod(const std::string& method, const std::string& param,
142     const std::function<void(std::string&)>& callback)
143 {
144     if (method.empty()) {
145         return;
146     }
147 
148     auto context = context_.Upgrade();
149     if (!context) {
150         LOGE("fail to get context to call res register method");
151         return;
152     }
153 
154     auto resRegister = context->GetPlatformResRegister();
155     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(),
156                                                          TaskExecutor::TaskType::PLATFORM);
157 
158     auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
159     platformTaskExecutor.PostTask(
160         [method, param, weakRes, callback] {
161             auto resRegister = weakRes.Upgrade();
162             if (resRegister == nullptr) {
163                 LOGE("resRegister is nullptr");
164                 return;
165             }
166             std::string result;
167             resRegister->OnMethodCall(method, param, result);
168             if (callback) {
169                 callback(result);
170             }
171         },
172         "ArkUIRichTextCallResRegister");
173 }
174 
GetStringParam(const std::string & param,const std::string & name) const175 std::string RichTextResource::GetStringParam(const std::string& param, const std::string& name) const
176 {
177     size_t len = name.length();
178     size_t pos = param.find(name);
179     std::string result;
180 
181     if (pos != std::string::npos) {
182         std::stringstream ss;
183 
184         ss << param.substr(pos + 1 + len);
185         ss >> result;
186     }
187     return result;
188 }
189 
190 } // namespace OHOS::Ace