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/plugin/resource/plugin_manager_delegate.h"
17
18 #include <algorithm>
19 #include <iomanip>
20 #include <sstream>
21
22 #include "base/log/log.h"
23 #include "frameworks/base/json/json_util.h"
24
25 #ifdef OHOS_STANDARD_SYSTEM
26 #include "frameworks/core/components/plugin/resource/plugin_callback_client.h"
27 #endif
28
29 namespace OHOS::Ace {
30 namespace {
31 constexpr char PLUGIN_EVENT_ON_PLUGIN_COMPLETE[] = "onPluginComplete";
32 constexpr char PLUGIN_EVENT_ON_UPDATE_PLUGIN[] = "onUpdatePlugin";
33 constexpr char PLUGIN_EVENT_ON_ERROR[] = "onPluginError";
34 constexpr char PLUGIN_ADAPTOR_RESOURCE_NAME[] = "pluginAdaptor";
35 constexpr char NTC_PARAM_RICH_TEXT[] = "pluginAdaptor";
36 } // namespace
37
~PluginManagerDelegate()38 PluginManagerDelegate::~PluginManagerDelegate()
39 {
40 }
41
UnregisterEvent()42 void PluginManagerDelegate::UnregisterEvent()
43 {
44 auto context = context_.Upgrade();
45 if (!context) {
46 LOGE("fail to get context when unregister event");
47 return;
48 }
49 auto resRegister = context->GetPlatformResRegister();
50 resRegister->UnregisterEvent(MakeEventHash(PLUGIN_EVENT_ON_PLUGIN_COMPLETE));
51 resRegister->UnregisterEvent(MakeEventHash(PLUGIN_EVENT_ON_UPDATE_PLUGIN));
52 resRegister->UnregisterEvent(MakeEventHash(PLUGIN_EVENT_ON_ERROR));
53 }
54
RegisterEvent()55 void PluginManagerDelegate::RegisterEvent()
56 {
57 auto context = context_.Upgrade();
58 if (!context) {
59 LOGE("register event error due null context, will not receive plugin manager event");
60 return;
61 }
62 auto resRegister = context->GetPlatformResRegister();
63 resRegister->RegisterEvent(
64 MakeEventHash(PLUGIN_EVENT_ON_PLUGIN_COMPLETE), [weak = WeakClaim(this)](const std::string& param) {
65 auto delegate = weak.Upgrade();
66 if (delegate) {
67 delegate->OnPluginComplete(param);
68 }
69 });
70 resRegister->RegisterEvent(
71 MakeEventHash(PLUGIN_EVENT_ON_UPDATE_PLUGIN), [weak = WeakClaim(this)](const std::string& param) {
72 auto delegate = weak.Upgrade();
73 if (delegate) {
74 delegate->OnPluginUpdate(param);
75 }
76 });
77 resRegister->RegisterEvent(
78 MakeEventHash(PLUGIN_EVENT_ON_ERROR), [weak = WeakClaim(this)](const std::string& param) {
79 auto delegate = weak.Upgrade();
80 if (delegate) {
81 delegate->OnPluginError(param);
82 }
83 });
84 }
85
CreatePlatformResource(const WeakPtr<PipelineBase> & context,const RequestPluginInfo & info)86 void PluginManagerDelegate::CreatePlatformResource(
87 const WeakPtr<PipelineBase>& context, const RequestPluginInfo& info)
88 {
89 context_ = context;
90 state_ = State::CREATING;
91
92 auto pipelineContext = context.Upgrade();
93 if (!pipelineContext) {
94 state_ = State::CREATEFAILED;
95 OnPluginError("internal error");
96 return;
97 }
98 auto platformTaskExecutor =
99 SingleTaskExecutor::Make(pipelineContext->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
100 auto resRegister = pipelineContext->GetPlatformResRegister();
101 auto weakRes = AceType::WeakClaim(AceType::RawPtr(resRegister));
102 platformTaskExecutor.PostTask([weak = WeakClaim(this), weakRes, info] {
103 auto delegate = weak.Upgrade();
104 if (!delegate) {
105 LOGE("delegate is null");
106 return;
107 }
108 auto resRegister = weakRes.Upgrade();
109 auto context = delegate->context_.Upgrade();
110 if (!resRegister || !context) {
111 return;
112 }
113
114 delegate->id_ = CREATING_ID;
115
116 std::stringstream paramStream;
117 paramStream << NTC_PARAM_RICH_TEXT << PLUGIN_MANAGER_PARAM_EQUALS << delegate->id_ << PLUGIN_MANAGER_PARAM_AND
118 << "bundle" << PLUGIN_MANAGER_PARAM_EQUALS << info.bundleName << PLUGIN_MANAGER_PARAM_AND
119 << "ability" << PLUGIN_MANAGER_PARAM_EQUALS << info.abilityName << PLUGIN_MANAGER_PARAM_AND
120 << "module" << PLUGIN_MANAGER_PARAM_EQUALS << info.moduleName << PLUGIN_MANAGER_PARAM_AND
121 << "name" << PLUGIN_MANAGER_PARAM_EQUALS << info.pluginName << PLUGIN_MANAGER_PARAM_AND
122 << "dimension" << PLUGIN_MANAGER_PARAM_EQUALS << info.dimension << PLUGIN_MANAGER_PARAM_AND
123 << "id" << PLUGIN_MANAGER_PARAM_EQUALS << info.id << PLUGIN_MANAGER_PARAM_AND;
124
125 std::string param = paramStream.str();
126 delegate->id_ = resRegister->CreateResource(PLUGIN_ADAPTOR_RESOURCE_NAME, param);
127 if (delegate->id_ == INVALID_ID) {
128 return;
129 }
130 delegate->state_ = State::CREATED;
131 delegate->hash_ = delegate->MakeResourceHash();
132 delegate->RegisterEvent();
133 });
134 OnPluginComplete("Complete");
135 }
136
AddPlugin(const WeakPtr<PipelineBase> & context,const RequestPluginInfo & info)137 void PluginManagerDelegate::AddPlugin(const WeakPtr<PipelineBase>& context, const RequestPluginInfo& info)
138 {
139 LOGI("PluginManagerDelegate::AddPlugin");
140 CreatePlatformResource(context, info);
141 }
142
AddPluginCompleteCallback(const OnPluginCompleteCallback & callback)143 void PluginManagerDelegate::AddPluginCompleteCallback(const OnPluginCompleteCallback& callback)
144 {
145 if (!callback || state_ == State::RELEASED) {
146 LOGE("callback is null or has released");
147 return;
148 }
149 onPluginCompleteCallback_ = callback;
150 }
151
AddPluginUpdateCallback(const OnPluginUpdateCallback & callback)152 void PluginManagerDelegate::AddPluginUpdateCallback(const OnPluginUpdateCallback& callback)
153 {
154 if (!callback || state_ == State::RELEASED) {
155 LOGE("callback is null or has released");
156 return;
157 }
158 onPluginUpdateCallback_ = callback;
159 }
160
AddPluginErrorCallback(const OnPluginErrorCallback & callback)161 void PluginManagerDelegate::AddPluginErrorCallback(const OnPluginErrorCallback& callback)
162 {
163 if (!callback || state_ == State::RELEASED) {
164 LOGE("callback is null or has released");
165 return;
166 }
167 onPluginErrorCallback_ = callback;
168 }
169
OnActionEvent(const std::string & action)170 void PluginManagerDelegate::OnActionEvent(const std::string& action)
171 {
172 auto eventAction = JsonUtil::ParseJsonString(action);
173 if (!eventAction->IsValid()) {
174 LOGE("get event action failed");
175 return;
176 }
177 auto actionType = eventAction->GetValue("action");
178 if (!actionType->IsValid()) {
179 LOGE("get event key failed");
180 return;
181 }
182
183 auto type = actionType->GetString();
184 if (type != "router" && type != "message") {
185 LOGE("undefined event type");
186 return;
187 }
188 }
189
OnPluginComplete(const std::string & param)190 void PluginManagerDelegate::OnPluginComplete(const std::string& param)
191 {
192 LOGI("PluginManagerDelegate::OnPluginComplete");
193 auto result = ParseMapFromString(param);
194 if (onPluginCompleteCallback_) {
195 LOGI("PluginManagerDelegate::OnPluginComplete");
196 onPluginCompleteCallback_();
197 }
198 }
199
OnPluginUpdate(const std::string & param)200 void PluginManagerDelegate::OnPluginUpdate(const std::string& param)
201 {
202 auto result = ParseMapFromString(param);
203 if (onPluginUpdateCallback_) {
204 onPluginUpdateCallback_(StringUtils::StringToLongInt(result["pluginId"]), result["data"]);
205 }
206 }
207
OnPluginError(const std::string & param)208 void PluginManagerDelegate::OnPluginError(const std::string& param)
209 {
210 auto result = ParseMapFromString(param);
211 if (onPluginErrorCallback_) {
212 if (result["code"].empty()) {
213 result["code"] = "-1";
214 result["msg"] = param;
215 }
216 onPluginErrorCallback_(result["code"], result["msg"]);
217 }
218 }
219 } // namespace OHOS::Ace