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/hyperlink/hyperlink_resources.h"
17
18 namespace OHOS::Ace {
19
20 const char HYPERLINK_COMPONENT_PARAM_EQUALS[] = "#HWJS-=-#";
21 const char HYPERLINK_COMPONENT_PARAM_BEGIN[] = "#HWJS-?-#";
22 const char HYPERLINK_COMPONENT_METHOD[] = "method";
23 const char HYPERLINK_STARTABILITY[] = "startAbility";
24 const char HYPERLINK_URI[] = "url";
25 const char HYPERLINK_PARAM[] = "hyperlink";
26 const char HYPER_CREATE_PARAM[] = "hyperlink#HWJS-=-#startAbility";
27
~HyperlinkResources()28 HyperlinkResources::~HyperlinkResources()
29 {
30 ReleasePluginResource();
31 }
32
MakeResourceHash() const33 std::string HyperlinkResources::MakeResourceHash() const
34 {
35 std::stringstream hashCode;
36 hashCode << HYPERLINK_PARAM << "@" << id_;
37 return hashCode.str();
38 }
39
MakeMethodHash(const std::string & method) const40 std::string HyperlinkResources::MakeMethodHash(const std::string& method) const
41 {
42 // method hash is hyperlink@(id)method#HWJS-=-#(method)#HWJS-?-#
43 std::string methodHash = MakeResourceHash();
44 methodHash += std::string(HYPERLINK_COMPONENT_METHOD);
45 methodHash += std::string(HYPERLINK_COMPONENT_PARAM_EQUALS);
46 methodHash += method;
47 methodHash += std::string(HYPERLINK_COMPONENT_PARAM_BEGIN);
48 return methodHash;
49 }
50
CallResRegisterMethod(const std::string & method,const std::string & param)51 std::string HyperlinkResources::CallResRegisterMethod(const std::string& method, const std::string& param)
52 {
53 if (method.empty()) {
54 return "";
55 }
56
57 auto context = context_.Upgrade();
58 if (!context) {
59 LOGE("fail to get context to call res register method");
60 return "";
61 }
62
63 auto resRegister = context->GetPlatformResRegister();
64 if (id_ == INVALID_ID) {
65 LOGE("fail to get a valid id");
66 return "";
67 }
68 auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
69 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
70
71 platformTaskExecutor.PostTask([method, param, weakRes] {
72 auto resRegister = weakRes.Upgrade();
73 if (resRegister != nullptr) {
74 std::string result;
75 resRegister->OnMethodCall(method, param, result);
76 }
77 }, "ArkUIHyperlinkCallResRegisterMethod");
78 return "";
79 }
80
StartAbility(const std::string & address)81 void HyperlinkResources::StartAbility(const std::string& address)
82 {
83 std::string startAbilityMethod = MakeMethodHash(HYPERLINK_STARTABILITY);
84 std::stringstream paramStream;
85 paramStream << HYPERLINK_URI << HYPERLINK_COMPONENT_PARAM_EQUALS << address;
86 std::string param = paramStream.str();
87 CallResRegisterMethod(startAbilityMethod, param);
88 }
89
CreatePlatformResource(const WeakPtr<PipelineContext> & context)90 void HyperlinkResources::CreatePlatformResource(const WeakPtr<PipelineContext>& context)
91 {
92 context_ = context;
93 CreatePluginResource(context);
94 }
95
CreatePluginResource(const WeakPtr<PipelineContext> & context)96 void HyperlinkResources::CreatePluginResource(const WeakPtr<PipelineContext>& context)
97 {
98 // create AceHyperlinkOhos with id
99 auto pipelineContext = context.Upgrade();
100 if (!pipelineContext) {
101 return;
102 }
103 context_ = context;
104 auto platformTaskExecutor =
105 SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
106 auto resRegister = pipelineContext->GetPlatformResRegister();
107 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
108 platformTaskExecutor.PostTask([weak = WeakClaim(this), weakRes] {
109 auto hyperlinkResource = weak.Upgrade();
110 if (!hyperlinkResource) {
111 return;
112 }
113 auto resRegister = weakRes.Upgrade();
114 if (!resRegister) {
115 return;
116 }
117 hyperlinkResource->id_ = resRegister->CreateResource(HYPERLINK_PARAM, HYPER_CREATE_PARAM);
118 }, "ArkUIHyperlinkCreatePluginResource");
119 }
120
ReleasePluginResource()121 void HyperlinkResources::ReleasePluginResource()
122 {
123 // release AceHyperlinkOhos by id
124 auto context = context_.Upgrade();
125 if (!context) {
126 LOGE("fail to release resource due to context is null");
127 return;
128 }
129 auto resRegister = context->GetPlatformResRegister();
130 auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
131 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
132 hash_ = MakeResourceHash();
133 auto releaseTask = [id = id_, hash = hash_, weakRes] {
134 if (id == INVALID_ID) {
135 LOGW("ability component resource has released");
136 return;
137 }
138
139 auto resRegister = weakRes.Upgrade();
140 if (resRegister) {
141 resRegister->ReleaseResource(hash);
142 }
143 };
144 if (platformTaskExecutor.IsRunOnCurrentThread()) {
145 releaseTask();
146 } else {
147 platformTaskExecutor.PostTask(releaseTask, "ArkUIHyperlinkReleasePluginResource");
148 }
149 }
150
151 } // namespace OHOS::Ace
152