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/xcomponent/resource/xcomponent_resource.h"
17 
18 #include <sstream>
19 
20 #include "base/log/log.h"
21 
22 namespace OHOS::Ace {
23 const char XCOMPONENT_PARAM_INIT[] = "initParam";
24 const char XCOMPONENT_PARAM_NONE[] = "";
25 const char XCOMPONENT_PARAM_AND[] = "#HWJS-&-#";
26 const char XCOMPONENT_PARAM_VALUE[] = "value";
27 const char XCOMPONENT_PARAM_EQUALS[] = "#HWJS-=-#";
28 const char XCOMPONENT_PARAM_BEGIN[] = "#HWJS-?-#";
29 const char XCOMPONENT_METHOD[] = "method";
30 const char XCOMPONENT_EVENT[] = "event";
31 const char XCOMPONENT_RESULT_FAIL[] = "fail";
32 
Release(const std::function<void (bool)> & onRelease)33 void XComponentResource::Release(const std::function<void(bool)>& onRelease)
34 {
35     if (id_ == X_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     if (!resRegister) {
47         LOGE("fail to release resource due to resRegister is null");
48         return;
49     }
50 
51     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(),
52                                                          TaskExecutor::TaskType::PLATFORM);
53     auto releaseTask = [this, resRegister, onRelease] {
54         bool ret = resRegister->ReleaseResource(hash_);
55         if (ret) {
56             id_ = X_INVALID_ID;
57             hash_.clear();
58         }
59 
60         if (onRelease) {
61             onRelease(ret);
62         }
63     };
64     if (platformTaskExecutor.IsRunOnCurrentThread()) {
65         releaseTask();
66     } else {
67         platformTaskExecutor.PostTask(releaseTask, "ArkUIXComponentRelease");
68     }
69 }
70 
GetDoubleParam(const std::string & param,const std::string & name) const71 double XComponentResource::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 XComponentResource::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 
MakeResourceHash() const103 std::string XComponentResource::MakeResourceHash() const
104 {
105     std::stringstream hashCode;
106     hashCode << type_ << "@" << id_;
107 
108     return hashCode.str();
109 }
110 
MakeEventHash(const std::string & event) const111 std::string XComponentResource::MakeEventHash(const std::string& event) const
112 {
113     std::string eventHash = hash_;
114 
115     eventHash += std::string(XCOMPONENT_EVENT);
116     eventHash += std::string(XCOMPONENT_PARAM_EQUALS);
117     eventHash += event;
118     eventHash += std::string(XCOMPONENT_PARAM_BEGIN);
119 
120     return eventHash;
121 }
122 
MakeMethodHash(const std::string & method) const123 std::string XComponentResource::MakeMethodHash(const std::string& method) const
124 {
125     std::string methodHash = hash_;
126 
127     methodHash += std::string(XCOMPONENT_METHOD);
128     methodHash += std::string(XCOMPONENT_PARAM_EQUALS);
129     methodHash += method;
130     methodHash += std::string(XCOMPONENT_PARAM_BEGIN);
131 
132     return methodHash;
133 }
134 
OnError(const std::string & errorCode,const std::string & errorMsg)135 void XComponentResource::OnError(const std::string& errorCode, const std::string& errorMsg)
136 {
137     if (onError_) {
138         onError_(errorCode, errorMsg);
139     }
140 }
141 
CallResRegisterMethod(const std::string & method,const std::string & param,const std::function<void (std::string &)> & callback)142 void XComponentResource::CallResRegisterMethod(const std::string& method,
143                                                const std::string& param,
144                                                const std::function<void(std::string&)>& callback)
145 {
146     if (method.empty()) {
147         return;
148     }
149 
150     auto context = context_.Upgrade();
151     if (!context) {
152         LOGE("fail to get context to call res register method");
153         return;
154     }
155 
156     auto resRegister = context->GetPlatformResRegister();
157     if (!resRegister) {
158         LOGE("fail to CallResRegisterMethod due to resRegister is null");
159         return;
160     }
161 
162     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(),
163                                                          TaskExecutor::TaskType::PLATFORM);
164 
165     platformTaskExecutor.PostTask([method, param, resRegister, callback] {
166         std::string result;
167         resRegister->OnMethodCall(method, param, result);
168         if (callback) {
169             callback(result);
170         }
171     }, "ArkUIXComponentCallResRegisterMethod");
172 }
173 
GetStringParam(const std::string & param,const std::string & name) const174 std::string XComponentResource::GetStringParam(const std::string& param, const std::string& name) const
175 {
176     size_t len = name.length();
177     size_t pos = param.find(name);
178     std::string result;
179 
180     if (pos != std::string::npos) {
181         std::stringstream ss;
182 
183         ss << param.substr(pos + 1 + len);
184         ss >> result;
185     }
186     return result;
187 }
188 } // namespace OHOS::Ace