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 "gtest/gtest.h"
17
18 #include "base/test/mock/mock_asset_manager.h"
19 #include "core/common/flutter/flutter_task_executor.h"
20 #include "core/common/test/mock/mock_resource_register.h"
21 #define private public
22 #define protected public
23 #include "bridge/plugin_frontend/plugin_frontend_delegate.h"
24 #undef private
25 #undef protected
26 #include "bridge/js_frontend/engine/common/js_engine_loader.h"
27 #include "bridge/js_frontend/frontend_delegate_impl.h"
28 #include "bridge/plugin_frontend/plugin_frontend.h"
29
30 using namespace testing;
31 using namespace testing::ext;
32
33 namespace OHOS::Ace {
34 namespace {
35 constexpr int32_t INVALID_PAGE_ID = -1;
36 } // namespace
37 class PluginFrontendDelegateTest : public testing::Test {
38 public:
SetUpTestCase()39 static void SetUpTestCase() {}
TearDownTestCase()40 static void TearDownTestCase() {}
SetUp()41 void SetUp() {}
TearDown()42 void TearDown() {}
43 static RefPtr<Framework::PluginFrontendDelegate> GetPluginFrontendDelegate(
44 const RefPtr<TaskExecutor>& taskExecutor);
45 static RefPtr<PipelineContext> GetPipelineContext(const RefPtr<PluginFrontend>& frontend);
46 };
47
GetPipelineContext(const RefPtr<PluginFrontend> & frontend)48 RefPtr<PipelineContext> PluginFrontendDelegateTest::GetPipelineContext(const RefPtr<PluginFrontend>& frontend)
49 {
50 auto platformWindow = PlatformWindow::Create(nullptr);
51 auto window = std::make_unique<Window>(std::move(platformWindow));
52 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
53 taskExecutor->InitJsThread(false);
54 auto assetManager = Referenced::MakeRefPtr<MockAssetManager>();
55 auto resRegister = Referenced::MakeRefPtr<MockResourceRegister>();
56 return AceType::MakeRefPtr<PipelineContext>(
57 std::move(window), taskExecutor, assetManager, resRegister, frontend, 0);
58 }
59
GetPluginFrontendDelegate(const RefPtr<TaskExecutor> & taskExecutor)60 RefPtr<Framework::PluginFrontendDelegate> PluginFrontendDelegateTest::GetPluginFrontendDelegate(
61 const RefPtr<TaskExecutor>& taskExecutor)
62 {
63 auto& loader = Framework::JsEngineLoader::Get("libace_engine_ark.z.so");
64 auto jsEngine = loader.CreateJsEngine(0);
65 const auto& loadCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](const std::string& url,
66 const RefPtr<Framework::JsAcePage>& jsPage, bool isMainPage) {
67 auto jsEngine = weakEngine.Upgrade();
68 if (!jsEngine) {
69 return;
70 }
71 jsEngine->LoadJs(url, jsPage, isMainPage);
72 };
73
74 const auto& setPluginMessageTransferCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
75 const RefPtr<JsMessageDispatcher>& dispatcher) {
76 auto jsEngine = weakEngine.Upgrade();
77 if (!jsEngine) {
78 return;
79 }
80 jsEngine->SetJsMessageDispatcher(dispatcher);
81 };
82
83 const auto& asyncEventCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
84 const std::string& eventId, const std::string& param) {
85 auto jsEngine = weakEngine.Upgrade();
86 if (!jsEngine) {
87 return;
88 }
89 jsEngine->FireAsyncEvent(eventId, param);
90 };
91
92 const auto& syncEventCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
93 const std::string& eventId, const std::string& param) {
94 auto jsEngine = weakEngine.Upgrade();
95 if (!jsEngine) {
96 return;
97 }
98 jsEngine->FireSyncEvent(eventId, param);
99 };
100
101 const auto& updatePageCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
102 const RefPtr<Framework::JsAcePage>& jsPage) {
103 auto jsEngine = weakEngine.Upgrade();
104 if (!jsEngine) {
105 return;
106 }
107 jsEngine->UpdateRunningPage(jsPage);
108 jsEngine->UpdateStagingPage(jsPage);
109 };
110
111 const auto& resetStagingPageCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)]() {
112 auto jsEngine = weakEngine.Upgrade();
113 if (!jsEngine) {
114 return;
115 }
116 jsEngine->ResetStagingPage();
117 };
118
119 const auto& destroyPageCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](int32_t pageId) {
120 auto jsEngine = weakEngine.Upgrade();
121 if (!jsEngine) {
122 return;
123 }
124 jsEngine->DestroyPageInstance(pageId);
125 };
126
127 const auto& destroyApplicationCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
128 const std::string& packageName) {
129 auto jsEngine = weakEngine.Upgrade();
130 if (!jsEngine) {
131 return;
132 }
133 jsEngine->DestroyApplication(packageName);
134 };
135
136 const auto& updateApplicationStateCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
137 const std::string& packageName, Frontend::State state) {
138 auto jsEngine = weakEngine.Upgrade();
139 if (!jsEngine) {
140 return;
141 }
142 jsEngine->UpdateApplicationState(packageName, state);
143 };
144
145 const auto& onWindowDisplayModeChangedCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
146 bool isShownInMultiWindow, const std::string& data) {
147 auto jsEngine = weakEngine.Upgrade();
148 if (!jsEngine) {
149 return;
150 }
151 jsEngine->OnWindowDisplayModeChanged(isShownInMultiWindow, data);
152 };
153
154 const auto& onSaveAbilityStateCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](std::string& data) {
155 auto jsEngine = weakEngine.Upgrade();
156 if (!jsEngine) {
157 LOGE("the js engine is nullptr");
158 return;
159 }
160 jsEngine->OnSaveAbilityState(data);
161 };
162 const auto& onRestoreAbilityStateCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
163 const std::string& data) {
164 auto jsEngine = weakEngine.Upgrade();
165 if (!jsEngine) {
166 LOGE("the js engine is nullptr");
167 return;
168 }
169 jsEngine->OnRestoreAbilityState(data);
170 };
171
172 const auto& onNewWantCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](const std::string& data) {
173 auto jsEngine = weakEngine.Upgrade();
174 if (!jsEngine) {
175 LOGE("the js engine is nullptr");
176 return;
177 }
178 jsEngine->OnNewWant(data);
179 };
180 const auto& onActiveCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)]() {
181 auto jsEngine = weakEngine.Upgrade();
182 if (!jsEngine) {
183 return;
184 }
185 jsEngine->OnActive();
186 };
187
188 const auto& onInactiveCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)]() {
189 auto jsEngine = weakEngine.Upgrade();
190 if (!jsEngine) {
191 return;
192 }
193 jsEngine->OnInactive();
194 };
195
196 const auto& onConfigurationUpdatedCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
197 const std::string& data) {
198 auto jsEngine = weakEngine.Upgrade();
199 if (!jsEngine) {
200 return;
201 }
202 jsEngine->OnConfigurationUpdated(data);
203 };
204
205 const auto& timerCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
206 const std::string& callbackId, const std::string& delay, bool isInterval) {
207 auto jsEngine = weakEngine.Upgrade();
208 if (!jsEngine) {
209 return;
210 }
211 jsEngine->TimerCallback(callbackId, delay, isInterval);
212 };
213
214 const auto& mediaQueryCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
215 const std::string& callbackId, const std::string& args) {
216 auto jsEngine = weakEngine.Upgrade();
217 if (!jsEngine) {
218 return;
219 }
220 jsEngine->MediaQueryCallback(callbackId, args);
221 };
222
223 const auto& requestAnimationCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
224 const std::string& callbackId, uint64_t timeStamp) {
225 auto jsEngine = weakEngine.Upgrade();
226 if (!jsEngine) {
227 return;
228 }
229 jsEngine->RequestAnimationCallback(callbackId, timeStamp);
230 };
231
232 const auto& jsCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
233 const std::string& callbackId, const std::string& args) {
234 auto jsEngine = weakEngine.Upgrade();
235 if (!jsEngine) {
236 return;
237 }
238 jsEngine->JsCallback(callbackId, args);
239 };
240
241 const auto& onMemoryLevelCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](const int32_t level) {
242 auto jsEngine = weakEngine.Upgrade();
243 if (!jsEngine) {
244 return;
245 }
246 jsEngine->OnMemoryLevel(level);
247 };
248
249 const auto& onStartContinuationCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)]() -> bool {
250 auto jsEngine = weakEngine.Upgrade();
251 if (!jsEngine) {
252 return false;
253 }
254 return jsEngine->OnStartContinuation();
255 };
256 const auto& onCompleteContinuationCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](int32_t code) {
257 auto jsEngine = weakEngine.Upgrade();
258 if (!jsEngine) {
259 return;
260 }
261 jsEngine->OnCompleteContinuation(code);
262 };
263 const auto& onRemoteTerminatedCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)]() {
264 auto jsEngine = weakEngine.Upgrade();
265 if (!jsEngine) {
266 return;
267 }
268 jsEngine->OnRemoteTerminated();
269 };
270 const auto& onSaveDataCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](std::string& savedData) {
271 auto jsEngine = weakEngine.Upgrade();
272 if (!jsEngine) {
273 return;
274 }
275 jsEngine->OnSaveData(savedData);
276 };
277 const auto& onRestoreDataCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine)](
278 const std::string& data) -> bool {
279 auto jsEngine = weakEngine.Upgrade();
280 if (!jsEngine) {
281 return false;
282 }
283 return jsEngine->OnRestoreData(data);
284 };
285 RefPtr<Framework::PluginFrontendDelegate> delegate =
286 AceType::MakeRefPtr<Framework::PluginFrontendDelegate>(taskExecutor, loadCallback,
287 setPluginMessageTransferCallback, asyncEventCallback, syncEventCallback, updatePageCallback,
288 resetStagingPageCallback, destroyPageCallback, destroyApplicationCallback, updateApplicationStateCallback,
289 timerCallback, mediaQueryCallback, requestAnimationCallback, jsCallback, onWindowDisplayModeChangedCallBack,
290 onConfigurationUpdatedCallBack, onSaveAbilityStateCallBack, onRestoreAbilityStateCallBack,
291 onNewWantCallBack, onActiveCallBack, onInactiveCallBack, onMemoryLevelCallBack, onStartContinuationCallBack,
292 onCompleteContinuationCallBack, onRemoteTerminatedCallBack, onSaveDataCallBack, onRestoreDataCallBack);
293 return delegate;
294 }
295
296 /**
297 * @tc.name: GetMinPlatformVersionTest001
298 * @tc.desc: Verify the GetMinPlatformVersion Interface of PluginFrontendDelegate work correctly.
299 * @tc.type: FUNC
300 */
301 HWTEST_F(PluginFrontendDelegateTest, GetMinPlatformVersionTest001, TestSize.Level1)
302 {
303 /**
304 * @tc.steps: step1. Build a PluginFrontendDelegate.
305 */
306 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
307 RefPtr<Framework::PluginFrontendDelegate> delegate =
308 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
309 EXPECT_TRUE(delegate != nullptr);
310 /**
311 * @tc.steps: step2. GetMinPlatformVersion.
312 * @tc.expected: step2. Get Min Platform Version success.
313 */
314 EXPECT_EQ(delegate->GetMinPlatformVersion(), 0);
315 }
316
317 /**
318 * @tc.name: AttachPipelineContextTest001
319 * @tc.desc: Verify the AttachPipelineContext Interface of PluginFrontendDelegate work success.
320 * @tc.type: FUNC
321 */
322 HWTEST_F(PluginFrontendDelegateTest, AttachPipelineContextTest001, TestSize.Level1)
323 {
324 /**
325 * @tc.steps: step1. Build a PluginFrontendDelegate.
326 */
327 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
328 RefPtr<Framework::PluginFrontendDelegate> delegate =
329 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
330 EXPECT_TRUE(delegate != nullptr);
331 /**
332 * @tc.steps: step2. GetMinPlatformVersion.
333 * @tc.expected: step2. Get Min Platform Version success.
334 */
335 RefPtr<PluginFrontend> pluginFrontend = Referenced::MakeRefPtr<PluginFrontend>();
336 auto pipelineContext = PluginFrontendDelegateTest::GetPipelineContext(pluginFrontend);
337 delegate->AttachPipelineContext(pipelineContext);
338 EXPECT_TRUE(delegate->GetPipelineContext() != nullptr);
339 }
340
341 /**
342 * @tc.name: GetUiTask001
343 * @tc.desc: Verify the GetUiTask Interface of PluginFrontendDelegate work success.
344 * @tc.type: FUNC
345 */
346 HWTEST_F(PluginFrontendDelegateTest, GetUiTask001, TestSize.Level1)
347 {
348 /**
349 * @tc.steps: step1. Build a PluginFrontendDelegate.
350 */
351 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
352 RefPtr<Framework::PluginFrontendDelegate> delegate =
353 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
354 EXPECT_TRUE(delegate != nullptr);
355 /**
356 * @tc.steps: step2. Get Ui Task.
357 * @tc.expected: step2. Get Ui Task success.
358 */
359 RefPtr<PluginFrontend> pluginFrontend = Referenced::MakeRefPtr<PluginFrontend>();
360 auto pipelineContext = PluginFrontendDelegateTest::GetPipelineContext(pluginFrontend);
361
362 EXPECT_TRUE(delegate->GetUiTask().GetTaskExecutor() != nullptr);
363 }
364
365 /**
366 * @tc.name: GetAnimationJsTask001
367 * @tc.desc: Verify the GetAnimationJsTask Interface of PluginFrontendDelegate work success.
368 * @tc.type: FUNC
369 */
370 HWTEST_F(PluginFrontendDelegateTest, GetAnimationJsTask001, TestSize.Level1)
371 {
372 /**
373 * @tc.steps: step1. Build a PluginFrontendDelegate.
374 */
375 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
376 RefPtr<Framework::PluginFrontendDelegate> delegate =
377 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
378 EXPECT_TRUE(delegate != nullptr);
379 /**
380 * @tc.steps: step2. Get Animation Js Task.
381 * @tc.expected: step2. Get Animation JsTask success.
382 */
383 EXPECT_TRUE(delegate->GetAnimationJsTask().GetTaskExecutor() != nullptr);
384 }
385
386 /**
387 * @tc.name: Initialize001
388 * @tc.desc: Verify the Initialize Interface of PluginFrontendDelegate work success.
389 * @tc.type: FUNC
390 */
391 HWTEST_F(PluginFrontendDelegateTest, Initialize001, TestSize.Level1)
392 {
393 /**
394 * @tc.steps: step1. Build a PluginFrontendDelegate.
395 */
396 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
397 RefPtr<Framework::PluginFrontendDelegate> delegate =
398 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
399 EXPECT_TRUE(delegate != nullptr);
400 /**
401 * @tc.steps: step2. Get Running Page Id.
402 * @tc.expected: step2. Get Running PageId success.
403 */
404 delegate->pageRouteStack_.emplace_back(Ace::Framework::PageInfo { 0, "url" });
405 EXPECT_EQ(delegate->GetRunningPageId(), 0);
406 }
407
408 /**
409 * @tc.name: GetRunningPageId002
410 * @tc.desc: Verify the GetRunningPageId Interface of PluginFrontendDelegate get invalid page id because page vector
411 * is empty.
412 * @tc.type: FUNC
413 */
414 HWTEST_F(PluginFrontendDelegateTest, GetRunningPageId002, TestSize.Level1)
415 {
416 /**
417 * @tc.steps: step1. Build a PluginFrontendDelegate.
418 */
419 auto taskExecutor = Referenced::MakeRefPtr<FlutterTaskExecutor>();
420 RefPtr<Framework::PluginFrontendDelegate> delegate =
421 PluginFrontendDelegateTest::GetPluginFrontendDelegate(taskExecutor);
422 EXPECT_TRUE(delegate != nullptr);
423 /**
424 * @tc.steps: step2. Get Running Page Id.
425 * @tc.expected: step2. Get invalid page id because page vector is empty.
426 */
427 EXPECT_EQ(delegate->GetRunningPageId(), INVALID_PAGE_ID);
428 }
429 } // namespace OHOS::Ace
430