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_app_service_extension.h"
33 #undef private
34 #undef protected
35 #include "js_app_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[] = "JsAppServiceExtension";
54 constexpr char DEFAULT_LANGUAGE[] = "zh_CN";
55 } // namespace
56
57 class JsAppServiceExtensionTest : 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<JsAppServiceExtension> jsAppServiceExtension_;
65 static std::shared_ptr<ApplicationContext> applicationContext_;
66 static std::unique_ptr<Runtime> jsRuntime_;
67
68 private:
69 static void CreateJsAppServiceExtension();
70 };
71
72 std::shared_ptr<JsAppServiceExtension> JsAppServiceExtensionTest::jsAppServiceExtension_ = nullptr;
73 std::shared_ptr<ApplicationContext> JsAppServiceExtensionTest::applicationContext_ = nullptr;
74 std::unique_ptr<Runtime> JsAppServiceExtensionTest::jsRuntime_ = nullptr;
75
SetUpTestCase()76 void JsAppServiceExtensionTest::SetUpTestCase()
77 {
78 CreateJsAppServiceExtension();
79 }
80
TearDownTestCase()81 void JsAppServiceExtensionTest::TearDownTestCase()
82 {}
83
SetUp()84 void JsAppServiceExtensionTest::SetUp()
85 {}
86
TearDown()87 void JsAppServiceExtensionTest::TearDown()
88 {}
89
CreateJsAppServiceExtension()90 void JsAppServiceExtensionTest::CreateJsAppServiceExtension()
91 {
92 std::shared_ptr<AbilityInfo> abilityInfo = std::make_shared<AbilityInfo>();
93 sptr<IRemoteObject> token(new (std::nothrow) MockAbilityToken());
94 auto record = std::make_shared<AbilityLocalRecord>(abilityInfo, token, nullptr, 0);
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 JsAppServiceExtension *extension = JsAppServiceExtension::Create(jsRuntime_);
135 ASSERT_NE(extension, nullptr);
136 jsAppServiceExtension_.reset(extension);
137
138 jsAppServiceExtension_->Init(record, application, handler, token);
139 }
140
141 /**
142 * @tc.name: Configuration_0100
143 * @tc.desc: Js app service extension init.
144 * @tc.type: FUNC
145 */
146 HWTEST_F(JsAppServiceExtensionTest, Init_0100, TestSize.Level1)
147 {
148 ASSERT_NE(jsAppServiceExtension_, nullptr);
149 ASSERT_NE(applicationContext_, nullptr);
150 auto context = jsAppServiceExtension_->GetContext();
151 ASSERT_NE(context, nullptr);
152
153 auto configuration = context->GetConfiguration();
154 ASSERT_NE(configuration, nullptr);
155
156 auto appConfig = applicationContext_->GetConfiguration();
157 ASSERT_NE(appConfig, nullptr);
158
159 // normally configuration is different, size is equal; cause LoadModule can't succeed, configuration is same.
160 EXPECT_EQ(configuration.get(), appConfig.get());
161 EXPECT_EQ(configuration->GetItemSize(), appConfig->GetItemSize());
162 auto language = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
163 EXPECT_EQ(language, DEFAULT_LANGUAGE);
164 auto colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
165 EXPECT_EQ(colorMode, ConfigurationInner::COLOR_MODE_LIGHT);
166 }
167
168 /**
169 * @tc.name: OnStart_0100
170 * @tc.desc: Js app service extension OnStart.
171 * @tc.type: FUNC
172 */
173 HWTEST_F(JsAppServiceExtensionTest, OnStart_0100, TestSize.Level1)
174 {
175 int displayId = Rosen::WindowScene::DEFAULT_DISPLAY_ID;
176 float originDensity;
177 std::string originDirection;
178 auto configUtils = std::make_shared<AbilityRuntime::ConfigurationUtils>();
179 auto ret = configUtils->GetDisplayConfig(displayId, originDensity, originDirection);
180 EXPECT_EQ(ret, true);
181
182 Want want;
183 ASSERT_NE(jsAppServiceExtension_, nullptr);
184 jsAppServiceExtension_->OnStart(want);
185
186 auto context = jsAppServiceExtension_->GetContext();
187 ASSERT_NE(context, nullptr);
188
189 auto configuration = context->GetConfiguration();
190 ASSERT_NE(configuration, nullptr);
191 auto resourceManager = context->GetResourceManager();
192 ASSERT_NE(resourceManager, nullptr);
193
194 auto appConfig = applicationContext_->GetConfiguration();
195 ASSERT_NE(appConfig, nullptr);
196
197 // configuration is larger than original
198 EXPECT_LE(configuration->GetItemSize(), appConfig->GetItemSize());
199
200 // check configuration
201 std::string displayIdStr = configuration->GetItem(ConfigurationInner::APPLICATION_DISPLAYID);
202 EXPECT_EQ(displayIdStr, std::to_string(displayId));
203 std::string densityStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
204 EXPECT_EQ(densityStr, GetDensityStr(originDensity));
205 std::string directionStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DIRECTION);
206 EXPECT_EQ(directionStr, originDirection);
207
208 // check resource manager
209 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
210 resourceManager->GetResConfig(*resConfig);
211 EXPECT_EQ(originDensity, resConfig->GetScreenDensity());
212 EXPECT_EQ(ConvertDirection(originDirection), resConfig->GetDirection());
213 }
214
215 /**
216 * @tc.name: OnConfigurationUpdated_0100
217 * @tc.desc: Js app service extension OnConfigurationUpdated.
218 * @tc.type: FUNC
219 */
220 HWTEST_F(JsAppServiceExtensionTest, OnConfigurationUpdated_0100, TestSize.Level1)
221 {
222 Configuration newConfig;
223 newConfig.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "en_US");
224 newConfig.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, ConfigurationInner::COLOR_MODE_DARK);
225 ASSERT_NE(jsAppServiceExtension_, nullptr);
226 jsAppServiceExtension_->OnConfigurationUpdated(newConfig);
227
228 auto context = jsAppServiceExtension_->GetContext();
229 ASSERT_NE(context, nullptr);
230 auto configuration = context->GetConfiguration();
231 ASSERT_NE(configuration, nullptr);
232
233 // check configuration
234 auto language = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
235 EXPECT_EQ(language, "en_US");
236 auto colorMode = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
237 EXPECT_EQ(colorMode, ConfigurationInner::COLOR_MODE_DARK);
238 }
239
240 /**
241 * @tc.name: OnCreate_0100
242 * @tc.desc: Js app service extension OnCreate.
243 * @tc.type: FUNC
244 */
245 HWTEST_F(JsAppServiceExtensionTest, OnCreate_0100, TestSize.Level1)
246 {
247 ASSERT_NE(jsAppServiceExtension_, nullptr);
248 Rosen::DisplayId displayId = 1;
249 jsAppServiceExtension_->OnCreate(displayId);
250 }
251
252 /**
253 * @tc.name: OnDestroy_0100
254 * @tc.desc: Js app service extension OnDestroy.
255 * @tc.type: FUNC
256 */
257 HWTEST_F(JsAppServiceExtensionTest, OnDestroy_0100, TestSize.Level1)
258 {
259 ASSERT_NE(jsAppServiceExtension_, nullptr);
260 Rosen::DisplayId displayId = 1;
261 jsAppServiceExtension_->OnDestroy(displayId);
262 }
263
264 /**
265 * @tc.name: OnChange_0100
266 * @tc.desc: Js app service extension OnChange.
267 * @tc.type: FUNC
268 */
269 HWTEST_F(JsAppServiceExtensionTest, OnChange_0100, TestSize.Level1)
270 {
271 int displayId = Rosen::WindowScene::DEFAULT_DISPLAY_ID;
272 float originDensity;
273 std::string originDirection;
274 auto configUtils = std::make_shared<AbilityRuntime::ConfigurationUtils>();
275 auto ret = configUtils->GetDisplayConfig(displayId, originDensity, originDirection);
276 EXPECT_EQ(ret, true);
277
278 ASSERT_NE(jsAppServiceExtension_, nullptr);
279 auto context = jsAppServiceExtension_->GetContext();
280 ASSERT_NE(context, nullptr);
281 auto configuration = context->GetConfiguration();
282 ASSERT_NE(configuration, nullptr);
283 auto resourceManager = context->GetResourceManager();
284 ASSERT_NE(resourceManager, nullptr);
285
286 configuration->RemoveItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
287
288 ASSERT_NE(jsAppServiceExtension_, nullptr);
289 jsAppServiceExtension_->OnChange(displayId);
290
291 // check configuration
292 std::string displayIdStr = configuration->GetItem(ConfigurationInner::APPLICATION_DISPLAYID);
293 EXPECT_EQ(displayIdStr, std::to_string(displayId));
294 std::string densityStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
295 EXPECT_EQ(densityStr, GetDensityStr(originDensity));
296 std::string directionStr = configuration->GetItem(displayId, ConfigurationInner::APPLICATION_DIRECTION);
297 EXPECT_EQ(directionStr, originDirection);
298
299 // check resource manager
300 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
301 resourceManager->GetResConfig(*resConfig);
302 EXPECT_EQ(originDensity, resConfig->GetScreenDensity());
303 EXPECT_EQ(ConvertDirection(originDirection), resConfig->GetDirection());
304 }
305 } // namespace AbilityRuntime
306 } // namespace OHOS
307