1 /*
2  * Copyright (c) 2022-2023 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 #include <gtest/hwext/gtest-multithread.h>
18 
19 #include "ability_handler.h"
20 #include "ability_local_record.h"
21 #include "configuration_convertor.h"
22 #define private public
23 #define protected public
24 #include "configuration_utils.h"
25 #undef private
26 #undef protected
27 #include "hilog_tag_wrapper.h"
28 #include "iremote_object.h"
29 #include "js_runtime.h"
30 #define private public
31 #define protected public
32 #include "js_service_extension.h"
33 #undef private
34 #undef protected
35 #include "js_service_extension_context.h"
36 #include "mock_ability_token.h"
37 #include "ohos_application.h"
38 #include "runtime.h"
39 #include "string_wrapper.h"
40 #include "want.h"
41 #ifdef SUPPORT_GRAPHICS
42 #include "locale_config.h"
43 #include "window_scene.h"
44 #endif
45 
46 using namespace testing;
47 using namespace testing::ext;
48 using namespace testing::mt;
49 
50 namespace OHOS {
51 namespace AbilityRuntime {
52 namespace {
53 constexpr char JS_SERVICE_EXTENSION_TASK_RUNNER[] = "JsServiceExtension";
54 constexpr char DEFAULT_LANGUAGE[] = "zh_CN";
55 } // namespace
56 
57 class JsServiceExtensionTest : public testing::Test {
58 public:
59     static void SetUpTestCase();
60     static void TearDownTestCase();
61     void SetUp() override;
62     void TearDown() override;
63 
64     static std::shared_ptr<JsServiceExtension> jsServiceExtension_;
65     static std::shared_ptr<ApplicationContext> applicationContext_;
66     static std::unique_ptr<Runtime> jsRuntime_;
67 
68 private:
69     static void CreateJsServiceExtension();
70 };
71 
72 std::shared_ptr<JsServiceExtension> JsServiceExtensionTest::jsServiceExtension_ = nullptr;
73 std::shared_ptr<ApplicationContext> JsServiceExtensionTest::applicationContext_ = nullptr;
74 std::unique_ptr<Runtime> JsServiceExtensionTest::jsRuntime_ = nullptr;
75 
SetUpTestCase()76 void JsServiceExtensionTest::SetUpTestCase()
77 {
78     CreateJsServiceExtension();
79 }
80 
TearDownTestCase()81 void JsServiceExtensionTest::TearDownTestCase()
82 {}
83 
SetUp()84 void JsServiceExtensionTest::SetUp()
85 {}
86 
TearDown()87 void JsServiceExtensionTest::TearDown()
88 {}
89 
CreateJsServiceExtension()90 void JsServiceExtensionTest::CreateJsServiceExtension()
91 {
92     std::shared_ptr<AbilityInfo> abilityInfo = std::make_shared<AbilityInfo>();
93     sptr<IRemoteObject> token(new (std::nothrow) MockAbilityToken());
94     std::shared_ptr<AbilityLocalRecord> record = std::make_shared<AbilityLocalRecord>(abilityInfo, token);
95 
96     std::shared_ptr<OHOSApplication> application = std::make_shared<OHOSApplication>();
97     std::shared_ptr<AbilityRuntime::ContextImpl> contextImpl = std::make_shared<AbilityRuntime::ContextImpl>();
98 
99     Configuration config;
100     config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, DEFAULT_LANGUAGE);
101     config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, ConfigurationInner::COLOR_MODE_LIGHT);
102     contextImpl->SetConfiguration(std::make_shared<Configuration>(config));
103 
104     std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
105     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
106 #ifdef SUPPORT_GRAPHICS
107     UErrorCode status = U_ZERO_ERROR;
108     icu::Locale locale = icu::Locale::forLanguageTag("zh", status);
109     TAG_LOGI(AAFwkTag::TEST, "language: %{public}s, script: %{public}s, region: %{public}s", locale.getLanguage(),
110              locale.getScript(), locale.getCountry());
111     resConfig->SetLocaleInfo(locale);
112 #endif
113     Global::Resource::RState updateRet = resourceManager->UpdateResConfig(*resConfig);
114     if (updateRet != Global::Resource::RState::SUCCESS) {
115         TAG_LOGE(AAFwkTag::TEST, "Init locale failed.");
116     }
117     contextImpl->SetResourceManager(resourceManager);
118 
119     std::shared_ptr<AbilityRuntime::ApplicationContext> applicationContext =
120         AbilityRuntime::ApplicationContext::GetInstance();
121     applicationContext->AttachContextImpl(contextImpl);
122     application->SetApplicationContext(applicationContext);
123     applicationContext_ = applicationContext;
124 
125     std::shared_ptr<AbilityHandler> handler = std::make_shared<AbilityHandler>(nullptr);
126 
127     auto eventRunner = AppExecFwk::EventRunner::Create(JS_SERVICE_EXTENSION_TASK_RUNNER);
128     Runtime::Options options;
129     options.preload = true;
130     options.eventRunner = eventRunner;
131     jsRuntime_ = JsRuntime::Create(options);
132     ASSERT_NE(jsRuntime_, nullptr);
133 
134     JsServiceExtension *extension = JsServiceExtension::Create(jsRuntime_);
135     ASSERT_NE(extension, nullptr);
136     jsServiceExtension_.reset(extension);
137 
138     jsServiceExtension_->Init(record, application, handler, token);
139 }
140 
141 /**
142  * @tc.name: Configuration_0100
143  * @tc.desc: Js service extension init.
144  * @tc.type: FUNC
145  * @tc.require: issueI7HPHB
146  */
147 HWTEST_F(JsServiceExtensionTest, Init_0100, TestSize.Level1)
148 {
149     ASSERT_NE(jsServiceExtension_, nullptr);
150     ASSERT_NE(applicationContext_, nullptr);
151     auto context = jsServiceExtension_->GetContext();
152     ASSERT_NE(context, nullptr);
153 
154     auto configuration = context->GetConfiguration();
155     ASSERT_NE(configuration, nullptr);
156 
157     auto appConfig = applicationContext_->GetConfiguration();
158     ASSERT_NE(appConfig, nullptr);
159 
160     // normally configuration is different, size is equal; cause LoadModule can't succeed, configuration is same.
161     EXPECT_EQ(configuration.get(), appConfig.get());
162     EXPECT_EQ(configuration->GetItemSize(), appConfig->GetItemSize());
163     auto language = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
164     EXPECT_EQ(language, DEFAULT_LANGUAGE);
165     auto colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
166     EXPECT_EQ(colorMode, ConfigurationInner::COLOR_MODE_LIGHT);
167 }
168 
169 /**
170  * @tc.name: OnStart_0100
171  * @tc.desc: Js service extension OnStart.
172  * @tc.type: FUNC
173  * @tc.require: issueI7HPHB
174  */
175 HWTEST_F(JsServiceExtensionTest, OnStart_0100, TestSize.Level1)
176 {
177     int displayId = Rosen::WindowScene::DEFAULT_DISPLAY_ID;
178     float originDensity;
179     std::string originDirection;
180     auto configUtils = std::make_shared<AbilityRuntime::ConfigurationUtils>();
181     auto ret = configUtils->GetDisplayConfig(displayId, originDensity, originDirection);
182     EXPECT_EQ(ret, true);
183 
184     Want want;
185     ASSERT_NE(jsServiceExtension_, nullptr);
186     jsServiceExtension_->OnStart(want);
187 
188     auto context = jsServiceExtension_->GetContext();
189     ASSERT_NE(context, nullptr);
190 
191     auto configuration = context->GetConfiguration();
192     ASSERT_NE(configuration, nullptr);
193     auto resourceManager = context->GetResourceManager();
194     ASSERT_NE(resourceManager, nullptr);
195 
196     auto appConfig = applicationContext_->GetConfiguration();
197     ASSERT_NE(appConfig, nullptr);
198 
199     // configuration is larger than original
200     EXPECT_LE(configuration->GetItemSize(), appConfig->GetItemSize());
201 
202     // check configuration
203     std::string displayIdStr = configuration->GetItem(ConfigurationInner::APPLICATION_DISPLAYID);
204     EXPECT_EQ(displayIdStr, std::to_string(displayId));
205     std::string densityStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
206     EXPECT_EQ(densityStr, GetDensityStr(originDensity));
207     std::string directionStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DIRECTION);
208     EXPECT_EQ(directionStr, originDirection);
209 
210     // check resource manager
211     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
212     resourceManager->GetResConfig(*resConfig);
213     EXPECT_EQ(originDensity, resConfig->GetScreenDensity());
214     EXPECT_EQ(ConvertDirection(originDirection), resConfig->GetDirection());
215 }
216 
217 /**
218  * @tc.name: OnConfigurationUpdated_0100
219  * @tc.desc: Js service extension OnConfigurationUpdated.
220  * @tc.type: FUNC
221  * @tc.require: issueI7HPHB
222  */
223 HWTEST_F(JsServiceExtensionTest, OnConfigurationUpdated_0100, TestSize.Level1)
224 {
225     Configuration newConfig;
226     newConfig.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "en_US");
227     newConfig.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, ConfigurationInner::COLOR_MODE_DARK);
228     ASSERT_NE(jsServiceExtension_, nullptr);
229     jsServiceExtension_->OnConfigurationUpdated(newConfig);
230 
231     auto context = jsServiceExtension_->GetContext();
232     ASSERT_NE(context, nullptr);
233     auto configuration = context->GetConfiguration();
234     ASSERT_NE(configuration, nullptr);
235 
236     // check configuration
237     auto language = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
238     EXPECT_EQ(language, "en_US");
239     auto colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
240     EXPECT_EQ(colorMode, ConfigurationInner::COLOR_MODE_DARK);
241 }
242 
243 /**
244  * @tc.name: OnCreate_0100
245  * @tc.desc: Js service extension OnCreate.
246  * @tc.type: FUNC
247  * @tc.require: issueI7HPHB
248  */
249 HWTEST_F(JsServiceExtensionTest, OnCreate_0100, TestSize.Level1)
250 {
251     ASSERT_NE(jsServiceExtension_, nullptr);
252     Rosen::DisplayId displayId = 1;
253     jsServiceExtension_->OnCreate(displayId);
254 }
255 
256 /**
257  * @tc.name: OnDestroy_0100
258  * @tc.desc: Js service extension OnDestroy.
259  * @tc.type: FUNC
260  * @tc.require: issueI7HPHB
261  */
262 HWTEST_F(JsServiceExtensionTest, OnDestroy_0100, TestSize.Level1)
263 {
264     ASSERT_NE(jsServiceExtension_, nullptr);
265     Rosen::DisplayId displayId = 1;
266     jsServiceExtension_->OnDestroy(displayId);
267 }
268 
269 /**
270  * @tc.name: OnChange_0100
271  * @tc.desc: Js service extension OnChange.
272  * @tc.type: FUNC
273  * @tc.require: issueI7HPHB
274  */
275 HWTEST_F(JsServiceExtensionTest, OnChange_0100, TestSize.Level1)
276 {
277     int displayId = Rosen::WindowScene::DEFAULT_DISPLAY_ID;
278     float originDensity;
279     std::string originDirection;
280     auto configUtils = std::make_shared<AbilityRuntime::ConfigurationUtils>();
281     auto ret = configUtils->GetDisplayConfig(displayId, originDensity, originDirection);
282     EXPECT_EQ(ret, true);
283 
284     ASSERT_NE(jsServiceExtension_, nullptr);
285     auto context = jsServiceExtension_->GetContext();
286     ASSERT_NE(context, nullptr);
287     auto configuration = context->GetConfiguration();
288     ASSERT_NE(configuration, nullptr);
289     auto resourceManager = context->GetResourceManager();
290     ASSERT_NE(resourceManager, nullptr);
291 
292     configuration->RemoveItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
293 
294     ASSERT_NE(jsServiceExtension_, nullptr);
295     jsServiceExtension_->OnChange(displayId);
296 
297     // check configuration
298     std::string displayIdStr = configuration->GetItem(ConfigurationInner::APPLICATION_DISPLAYID);
299     EXPECT_EQ(displayIdStr, std::to_string(displayId));
300     std::string densityStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
301     EXPECT_EQ(densityStr, GetDensityStr(originDensity));
302     std::string directionStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DIRECTION);
303     EXPECT_EQ(directionStr, originDirection);
304 
305     // check resource manager
306     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
307     resourceManager->GetResConfig(*resConfig);
308     EXPECT_EQ(originDensity, resConfig->GetScreenDensity());
309     EXPECT_EQ(ConvertDirection(originDirection), resConfig->GetDirection());
310 }
311 
312 /**
313  * @tc.name: HandleInsightIntent_0100
314  * @tc.desc: Js service extension HandleInsightIntent.
315  * @tc.type: FUNC
316  * @tc.require: issueI7HPHB
317  */
318 HWTEST_F(JsServiceExtensionTest, HandleInsightIntent_0100, TestSize.Level1)
319 {
320     ASSERT_NE(jsServiceExtension_, nullptr);
321     Want want;
322     WantParams wantParams;
323     std::string paramName(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_NAME);
324     std::string insightIntentId(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_ID);
325     wantParams.SetParam(paramName, String::Box("playMusic"));
326     wantParams.SetParam(insightIntentId, String::Box("1"));
327 
328     want.SetParams(wantParams);
329     AppExecFwk::ElementName element;
330     element.SetBundleName("com.ohos.test");
331     want.SetElement(element);
332 
333     auto ret = jsServiceExtension_->HandleInsightIntent(want);
334     EXPECT_TRUE(ret);
335 }
336 } // namespace AbilityRuntime
337 } // namespace OHOS
338