diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index d50ce1f10679051219f0a1b61b698fdf92c42a4a..bc24f05dd45143db6d6eb0018ab82dc491925034 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -64,6 +64,7 @@ group("moduletest") { "quick_fix:moduletest", "running_infos_module_test:moduletest", "start_option_display_id_test:moduletest", + "ui_extension_ability_test:moduletest", "//third_party/icu/icu4c:shared_icuuc", "//third_party/jsoncpp:jsoncpp", ] diff --git a/test/moduletest/ui_extension_ability_test/BUILD.gn b/test/moduletest/ui_extension_ability_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..625a69c20ebddaa16fd600a0cbb05090874a1efe --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +group("moduletest") { + testonly = true + + deps = [ + "ui_extension_connect_module_test:moduletest", + "ui_extension_provider_bundle:assisthap", + "ui_extension_user_bundle:assisthap", + ] +} diff --git a/test/moduletest/ui_extension_ability_test/ohos_test/BUILD.gn b/test/moduletest/ui_extension_ability_test/ohos_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..7b7ae726679736bd64ab35e5fd9763997a31865a --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ohos_test/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_copy("copy_ohos_test") { + subsystem_name = "ability" + part_name = "ability_runtime" + sources = [ "./ohos_test.xml" ] + outputs = [ "$root_out_dir/tests/moduletest/ability_runtime/ui_extension/resource/ohos_test.xml" ] +} diff --git a/test/moduletest/ui_extension_ability_test/ohos_test/ohos_test.xml b/test/moduletest/ui_extension_ability_test/ohos_test/ohos_test.xml new file mode 100644 index 0000000000000000000000000000000000000000..80067a7d98c0ca142bf96a304fa8e5f1b70892ce --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ohos_test/ohos_test.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/BUILD.gn b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..8c06a8e40be442744ba2bfdfc4ed47cd711c63ab --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/test.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_moduletest("ui_extension_connect_module_test") { + module_out_path = "ability_runtime/ui_extension" + + sources = [ + "ui_extension_connect_module_test.cpp", + "ui_extension_connect_module_test_connection.cpp", + "ui_extension_connect_module_test_observer.cpp", + ] + + configs = [ "${ability_runtime_services_path}/common:common_config" ] + + cflags = [] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "${ability_runtime_path}/test/moduletest/ui_extension_ability_test/ohos_test:copy_ohos_test", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ + "ability_base:session_info", + "ability_base:want", + "ability_runtime:ability_manager", + "ability_runtime:app_manager", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] +} + +group("moduletest") { + testonly = true + deps = [ ":ui_extension_connect_module_test" ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test.cpp b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e635c976adaf12d834558599d4c87a16d251e98 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test.cpp @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "ability_manager_client.h" +#include "ability_util.h" +#include "accesstoken_kit.h" +#include "app_mgr_interface.h" +#include "hilog_wrapper.h" +#include "nativetoken_kit.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "session_info.h" +#include "system_ability_definition.h" +#include "token_setproc.h" +#include "ui_extension_connect_module_test_connection.h" +#include "ui_extension_connect_module_test_observer.h" +#include "want.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace AAFwk { +namespace { +const int CONNECT_TIMEOUT_MS = 5 * 1000; +const int32_t MAIN_USER_ID = 100; + +const std::string TARGET_BUNDLE_NAME = "com.ohos.uiextensionprovider"; +const std::string TARGET_ABILITY_NAME = "UIExtensionProvider"; +const std::string TARGET_MODULE_NAME = "entry"; + +const std::string USER_BUNDLE_NAME = "com.ohos.uiextensionuser"; +const std::string USER_ABILITY_NAME = "EntryAbility"; +const std::string USER_MODULE_NAME = "entry"; + +static void SetNativeToken() +{ + uint64_t tokenId; + const char **perms = new const char *[2]; + perms[0] = "ohos.permission.CONNECT_UI_EXTENSION_ABILITY"; + perms[1] = "ohos.permission.RUNNING_STATE_OBSERVER"; + NativeTokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = 2, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .aplStr = "system_core", + }; + + infoInstance.processName = "SetUpTestCase"; + tokenId = GetAccessTokenId(&infoInstance); + SetSelfTokenID(tokenId); + OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo(); + delete[] perms; +} +} // namespace + +using IAbilityConnection = AppExecFwk::IAbilityConnection; +using IApplicationStateObserver = AppExecFwk::IApplicationStateObserver; + +class UIExtensionConnectModuleTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; + + void WaitUntilConnectDone(const sptr &connection); + void WaitUntilDisConnectDone(const sptr &connection); + void WaitUntilProcessCreated(const sptr &observer); + void WaitUntilProcessDied(const sptr &observer); + void WaitUntilAbilityForeground(const sptr &observer); + void WaitUntilAbilityBackground(const sptr &observer); + + void RegisterApplicationStateObserver(const sptr &observer); + void UnregisterApplicationStateObserver(const sptr &observer); + static sptr appMgr_; +}; + +sptr UIExtensionConnectModuleTest::appMgr_ = nullptr; + +void UIExtensionConnectModuleTest::SetUpTestCase(void) +{ + auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityMgr == nullptr) { + HILOG_ERROR("Failed to get SystemAbilityManager."); + return; + } + + auto remoteObj = systemAbilityMgr->GetSystemAbility(APP_MGR_SERVICE_ID); + if (remoteObj == nullptr) { + HILOG_ERROR("Remote object is nullptr."); + return; + } + + sptr appMgr = iface_cast(remoteObj); + if (appMgr == nullptr) { + HILOG_ERROR("App mgr is nullptr."); + return; + } + + appMgr_ = appMgr; +} + +void UIExtensionConnectModuleTest::TearDownTestCase(void) +{} + +void UIExtensionConnectModuleTest::SetUp() +{} + +void UIExtensionConnectModuleTest::TearDown() +{} + +void UIExtensionConnectModuleTest::RegisterApplicationStateObserver(const sptr &observer) +{ + std::vector bundleNameList; + bundleNameList.push_back(TARGET_BUNDLE_NAME); + bundleNameList.push_back(USER_BUNDLE_NAME); + auto ret = appMgr_->RegisterApplicationStateObserver(observer, bundleNameList); + if (ret != ERR_OK) { + HILOG_ERROR("Register failed."); + } +} + +void UIExtensionConnectModuleTest::UnregisterApplicationStateObserver(const sptr &observer) +{ + auto ret = appMgr_->UnregisterApplicationStateObserver(observer); + if (ret != ERR_OK) { + HILOG_ERROR("Unregister failed."); + } +} + +void UIExtensionConnectModuleTest::WaitUntilConnectDone(const sptr &connection) +{ + std::unique_lock lock(connection->connectMutex_); + auto waitStatus = connection->connectCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [connection]() { + return connection->connectFinished_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(connection->connectFinished_, true); +} + +void UIExtensionConnectModuleTest::WaitUntilDisConnectDone( + const sptr &connection) +{ + std::unique_lock lock(connection->connectMutex_); + auto waitStatus = connection->connectCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [connection]() { + return connection->disConnectFinished_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(connection->disConnectFinished_, true); +} + +void UIExtensionConnectModuleTest::WaitUntilProcessCreated(const sptr &observer) +{ + std::unique_lock lock(observer->observerMutex_); + auto waitStatus = observer->observerCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [observer]() { + return observer->processCreated_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(observer->processCreated_, true); +} + +void UIExtensionConnectModuleTest::WaitUntilProcessDied(const sptr &observer) +{ + std::unique_lock lock(observer->observerMutex_); + auto waitStatus = observer->observerCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [observer]() { + return observer->processDied_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(observer->processDied_, true); +} + +void UIExtensionConnectModuleTest::WaitUntilAbilityForeground( + const sptr &observer) +{ + std::unique_lock lock(observer->observerMutex_); + auto waitStatus = observer->observerCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [observer]() { + return observer->processForegrounded_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(observer->processForegrounded_, true); +} + +void UIExtensionConnectModuleTest::WaitUntilAbilityBackground( + const sptr &observer) +{ + std::unique_lock lock(observer->observerMutex_); + auto waitStatus = observer->observerCondation_.wait_for(lock, std::chrono::milliseconds(CONNECT_TIMEOUT_MS), + [observer]() { + return observer->processBackgrounded_; + }); + EXPECT_EQ(waitStatus, true); + EXPECT_EQ(observer->processBackgrounded_, true); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0100 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0100, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + Want providerWant; + AppExecFwk::ElementName providerElement("0", TARGET_BUNDLE_NAME, TARGET_ABILITY_NAME, TARGET_MODULE_NAME); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + // Connect ui extension ability firstly. + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + connectInfo->hostBundleName = USER_BUNDLE_NAME; + connectInfo->uiExtensionAbilityId = 0; + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_EQ(ret, ERR_OK); + HILOG_INFO("UIExtensonAbility id %{public}d", connectInfo->uiExtensionAbilityId); + EXPECT_NE(connectInfo->uiExtensionAbilityId, 0); + + // Wait until OnAbilityConnectDone has triggered. + WaitUntilConnectDone(connection); + + // Send uiextensionability id to ui extension user + // start ui extension user + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + ret = AbilityManagerClient::GetInstance()->StartAbility(userWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has foregrounded + WaitUntilAbilityForeground(observer); + + // Disconnect ui extension ability. + // wish can't be destroyed, cause there exist ui extension component. + ret = AbilityManagerClient::GetInstance()->DisconnectAbility(connection); + EXPECT_EQ(ret, ERR_OK); + + // Wait until OnAbilityDisconnectDone has triggered. + WaitUntilDisConnectDone(connection); + + // Destroy ui extension user, this testcase should executed in screen-on. + sptr token = nullptr; + ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + EXPECT_EQ(ret, ERR_OK); + + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has terminate + WaitUntilProcessDied(observer); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0200 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0200, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + Want providerWant; + AppExecFwk::ElementName providerElement("0", TARGET_BUNDLE_NAME, TARGET_ABILITY_NAME, TARGET_MODULE_NAME); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + // Connect ui extension ability firstly. + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + connectInfo->hostBundleName = USER_BUNDLE_NAME; + connectInfo->uiExtensionAbilityId = 0; + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_EQ(ret, ERR_OK); + HILOG_INFO("UIExtensonAbility id %{public}d", connectInfo->uiExtensionAbilityId); + EXPECT_NE(connectInfo->uiExtensionAbilityId, 0); + + // Wait until OnAbilityConnectDone has triggered. + WaitUntilConnectDone(connection); + + // start ui extension user + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + ret = AbilityManagerClient::GetInstance()->StartAbility(userWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has foregrounded + WaitUntilAbilityForeground(observer); + + // Destroy ui extension user. + sptr token = nullptr; + ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + EXPECT_EQ(ret, ERR_OK); + + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has background + WaitUntilAbilityBackground(observer); + + // Disconnect ui extension ability. + ret = AbilityManagerClient::GetInstance()->DisconnectAbility(connection); + EXPECT_EQ(ret, ERR_OK); + + // Wait until OnAbilityDisconnectDone has triggered. + WaitUntilDisConnectDone(connection); + + // Wait until ability has terminate + WaitUntilProcessDied(observer); + + SetSelfTokenID(currentId); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0300 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0300, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + // start ui extension user + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + auto ret = AbilityManagerClient::GetInstance()->StartAbility(userWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has foregrounded + WaitUntilAbilityForeground(observer); + + // Destroy ui extension user. + sptr token = nullptr; + ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Minimize ui extension user + ret = AbilityManagerClient::GetInstance()->MinimizeAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has background + WaitUntilAbilityBackground(observer); + + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has terminate + WaitUntilProcessDied(observer); + + SetSelfTokenID(currentId); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0400 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0400, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + Want providerWant; + AppExecFwk::ElementName providerElement("0", TARGET_BUNDLE_NAME, TARGET_ABILITY_NAME, TARGET_MODULE_NAME); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + // Connect ui extension ability firstly. + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + connectInfo->hostBundleName = USER_BUNDLE_NAME; + connectInfo->uiExtensionAbilityId = 0; + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_EQ(ret, ERR_OK); + HILOG_INFO("UIExtensonAbility id %{public}d", connectInfo->uiExtensionAbilityId); + EXPECT_NE(connectInfo->uiExtensionAbilityId, 0); + + // Wait until OnAbilityConnectDone has triggered. + WaitUntilConnectDone(connection); + + // Disconnect ui extension ability. + // wish can't be destroyed, cause there exist ui extension component. + ret = AbilityManagerClient::GetInstance()->DisconnectAbility(connection); + EXPECT_EQ(ret, ERR_OK); + + // Wait until OnAbilityDisconnectDone has triggered. + WaitUntilDisConnectDone(connection); + + // Wait until ability has terminate + WaitUntilProcessDied(observer); + + SetSelfTokenID(currentId); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0500 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0500, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + Want providerWant; + AppExecFwk::ElementName providerElement("0", TARGET_BUNDLE_NAME, TARGET_ABILITY_NAME, TARGET_MODULE_NAME); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + // Connect ui extension ability firstly. + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + connectInfo->hostBundleName = USER_BUNDLE_NAME; + connectInfo->uiExtensionAbilityId = 0; + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_EQ(ret, ERR_OK); + HILOG_INFO("UIExtensonAbility id %{public}d", connectInfo->uiExtensionAbilityId); + EXPECT_NE(connectInfo->uiExtensionAbilityId, 0); + + // Wait until OnAbilityConnectDone has triggered. + WaitUntilConnectDone(connection); + + // Send uiextensionability id to ui extension user + // start ui extension user + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + ret = AbilityManagerClient::GetInstance()->StartAbility(userWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has foregrounded + WaitUntilAbilityForeground(observer); + + // Disconnect ui extension ability. + // wish can't be destroyed, cause there exist ui extension component. + ret = AbilityManagerClient::GetInstance()->DisconnectAbility(connection); + EXPECT_EQ(ret, ERR_OK); + + // Wait until OnAbilityDisconnectDone has triggered. + WaitUntilDisConnectDone(connection); + + // Destroy ui extension user, this testcase should executed in screen-on. + sptr token = nullptr; + ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Minimize ui extension user + ret = AbilityManagerClient::GetInstance()->MinimizeAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has background + WaitUntilAbilityBackground(observer); + + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has terminate + WaitUntilProcessDied(observer); + + SetSelfTokenID(currentId); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + +/** + * @tc.name: ConnectUIExtensionAbility_0600 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectModuleTest, ConnectUIExtensionAbility_0600, TestSize.Level1) +{ + HILOG_INFO("start."); + + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + Want providerWant; + AppExecFwk::ElementName providerElement("0", TARGET_BUNDLE_NAME, TARGET_ABILITY_NAME, TARGET_MODULE_NAME); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + // Connect ui extension ability firstly. + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + connectInfo->hostBundleName = USER_BUNDLE_NAME; + connectInfo->uiExtensionAbilityId = 0; + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_EQ(ret, ERR_OK); + HILOG_INFO("UIExtensonAbility id %{public}d", connectInfo->uiExtensionAbilityId); + EXPECT_NE(connectInfo->uiExtensionAbilityId, 0); + + // Wait until OnAbilityConnectDone has triggered. + WaitUntilConnectDone(connection); + + // start ui extension user + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + ret = AbilityManagerClient::GetInstance()->StartAbility(userWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has foregrounded + WaitUntilAbilityForeground(observer); + + // Destroy ui extension user. + sptr token = nullptr; + ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Minimize ui extension user + ret = AbilityManagerClient::GetInstance()->MinimizeAbility(token); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has background + WaitUntilAbilityBackground(observer); + + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + EXPECT_EQ(ret, ERR_OK); + + // Wait until ability has background + WaitUntilAbilityBackground(observer); + + // Disconnect ui extension ability. + ret = AbilityManagerClient::GetInstance()->DisconnectAbility(connection); + EXPECT_EQ(ret, ERR_OK); + + // Wait until OnAbilityDisconnectDone has triggered. + WaitUntilDisConnectDone(connection); + + SetSelfTokenID(currentId); + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} +} // namespace AAFwk +} // namespace OHOS \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.cpp b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5695b9e14e501785dcffe523a010169dcb54b928 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_extension_connect_module_test_connection.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AAFwk { +void UIExtensionConnectModuleTestConnection::OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int resultCode) +{ + HILOG_INFO("element: %{public}s", element.GetURI().c_str()); + std::unique_lock lock(connectMutex_); + connectFinished_ = true; + connectCondation_.notify_one(); +} + +void UIExtensionConnectModuleTestConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, + int resultCode) +{ + HILOG_INFO("element: %{public}s", element.GetURI().c_str()); + std::unique_lock lock(connectMutex_); + disConnectFinished_ = true; + connectCondation_.notify_one(); +} +} // namespace AAFwk +} // namespace OHOS diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.h b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..3894bb1d87309a505741517273bccc8446a9844c --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_connection.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_CONNECTION_H +#define OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_CONNECTION_H + +#include "ability_connect_callback_stub.h" + +namespace OHOS { +namespace AAFwk { +class UIExtensionConnectModuleTestConnection : public AbilityConnectionStub { +public: + UIExtensionConnectModuleTestConnection() = default; + ~UIExtensionConnectModuleTestConnection() = default; + + std::condition_variable connectCondation_; + std::mutex connectMutex_; + bool connectFinished_ = false; + bool disConnectFinished_ = false; + +private: + void OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int resultCode) override; + void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_CONNECTION_H diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.cpp b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..459fdc3407885adbd7c9850556191e0df450f058 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_extension_connect_module_test_observer.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AAFwk { +namespace { +const std::string TARGET_BUNDLE_NAME = "com.ohos.uiextensionprovider"; +} // namespace + +void UIExtensionConnectModuleTestObserver::OnProcessCreated(const AppExecFwk::ProcessData &processData) +{ + HILOG_INFO("bundleName: %{public}s, abilityState: %{public}d", processData.bundleName.c_str(), processData.state); + std::unique_lock lock(observerMutex_); + if (processData.bundleName == TARGET_BUNDLE_NAME) { + processCreated_ = true; + observerCondation_.notify_one(); + } +} + +void UIExtensionConnectModuleTestObserver::OnProcessStateChanged(const AppExecFwk::ProcessData &processData) +{ + HILOG_INFO("bundleName: %{public}s, abilityState: %{public}d", processData.bundleName.c_str(), processData.state); + std::unique_lock lock(observerMutex_); + if (processData.bundleName == TARGET_BUNDLE_NAME) { + if (processData.state == AppExecFwk::AppProcessState::APP_STATE_FOREGROUND) { + processForegrounded_ = true; + observerCondation_.notify_one(); + } else if (processData.state == AppExecFwk::AppProcessState::APP_STATE_BACKGROUND) { + processBackgrounded_ = true; + observerCondation_.notify_one(); + } + } +} + +void UIExtensionConnectModuleTestObserver::OnProcessDied(const AppExecFwk::ProcessData &processData) +{ + HILOG_INFO("bundleName: %{public}s, abilityState: %{public}d", processData.bundleName.c_str(), processData.state); + std::unique_lock lock(observerMutex_); + if (processData.bundleName == TARGET_BUNDLE_NAME) { + processDied_ = true; + observerCondation_.notify_one(); + } +} + +void UIExtensionConnectModuleTestObserver::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) +{ + HILOG_INFO("bundleName: %{public}s, abilityState: %{public}d", abilityStateData.bundleName.c_str(), + abilityStateData.abilityState); +} + +void UIExtensionConnectModuleTestObserver::OnExtensionStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) +{ + HILOG_INFO("bundleName: %{public}s, abilityState: %{public}d", abilityStateData.bundleName.c_str(), + abilityStateData.abilityState); +} +} // namespace AAFwk +} // namespace OHOS diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.h b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..c988415ac0270551d3798b431582a375d2839981 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_connect_module_test/ui_extension_connect_module_test_observer.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_OBSERVER_H +#define OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_OBSERVER_H + +#include "application_state_observer_stub.h" + +namespace OHOS { +namespace AAFwk { +class UIExtensionConnectModuleTestObserver : public AppExecFwk::ApplicationStateObserverStub { +public: + UIExtensionConnectModuleTestObserver() = default; + ~UIExtensionConnectModuleTestObserver() = default; + + std::condition_variable observerCondation_; + std::mutex observerMutex_; + bool processCreated_ = false; + bool processForegrounded_ = false; + bool processBackgrounded_ = false; + bool processDied_ = false; + +private: + void OnProcessCreated(const AppExecFwk::ProcessData &processData) override; + void OnProcessStateChanged(const AppExecFwk::ProcessData &processData) override; + void OnProcessDied(const AppExecFwk::ProcessData &processData) override; + void OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) override; + void OnExtensionStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) override; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_UI_EXTENSION_CONNECT_MODULE_TEST_OBSERVER_H diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/app.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/app.json new file mode 100644 index 0000000000000000000000000000000000000000..64896469a1ca6c6e60c3ae8ed828d93957578955 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/app.json @@ -0,0 +1,12 @@ +{ + "app": { + "bundleName": "com.ohos.uiextensionprovider", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "minAPIVersion": 10, + "targetAPIVersion": 10 + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/element/string.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3d475cfa283e49167b2700c24fc4e904b8f26bad --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "UIExtensionProvider" + } + ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/media/app_icon.png b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/AppScope/resources/base/media/app_icon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/BUILD.gn b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1020906c0de2604d2089cc2582f9a2731b28b208 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_hap("ui_extension_provider_hap") { + hap_profile = "entry/src/main/module.json" + + deps = [ + ":ui_extension_provider_js_assets", + ":ui_extension_provider_resources", + ] + + ets2abc = true + certificate_profile = "signature/openharmony_sx.p7b" + hap_name = "ui_extension_provider" + subsystem_name = "ability" + part_name = "ability_runtime" + final_hap_path = "$root_out_dir/tests/moduletest/ability_runtime/ui_extension/resource/${hap_name}.hap" +} + +ohos_js_assets("ui_extension_provider_js_assets") { + hap_profile = "entry/src/main/module.json" + source_dir = "entry/src/main/ets" +} + +ohos_app_scope("ui_extension_provider_app_profile") { + app_profile = "AppScope/app.json" + sources = [ "AppScope/resources" ] +} + +ohos_resources("ui_extension_provider_resources") { + sources = [ "entry/src/main/resources" ] + deps = [ ":ui_extension_provider_app_profile" ] + hap_profile = "entry/src/main/module.json" +} + +group("assisthap") { + testonly = true + deps = [ ":ui_extension_provider_hap" ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/IIdlServiceExt.idl b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/IIdlServiceExt.idl new file mode 100644 index 0000000000000000000000000000000000000000..5e07d743c67ad03d7cfebed8e2e5adfd6917c649 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/IIdlServiceExt.idl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface OHOS.IIdlServiceExt { + int ProcessData([in] int data); + void InsertDataToMap([in] String key, [in] int val); +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts new file mode 100644 index 0000000000000000000000000000000000000000..66b27b45e2626a1a06fd6b0d35600e68b2e39779 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default interface IIdlServiceExt { + processData(data: number, callback: processDataCallback): void; + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void; +} +export type processDataCallback = (errCode: number, returnValue: number) => void; +export type insertDataToMapCallback = (errCode: number) => void; diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts new file mode 100644 index 0000000000000000000000000000000000000000..3cf1823646864952665f9b1ed7ecb5c701c47242 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { processDataCallback } from './i_idl_service_ext'; +import { insertDataToMapCallback } from './i_idl_service_ext'; +import IdlServiceExtStub from './idl_service_ext_stub'; + +const ERR_OK = 0; +const TAG: string = "[IdlServiceExtImpl]"; + +// 开发者需要在这个类型里对接口进行实现 +export default class ServiceExtImpl extends IdlServiceExtStub { + processData(data: number, callback: processDataCallback): void { + // 开发者自行实现业务逻辑 + console.info(TAG, `processData: ${data}`); + callback(ERR_OK, data + 1); + } + + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void { + // 开发者自行实现业务逻辑 + console.info(TAG, `insertDataToMap, key: ${key} val: ${val}`); + callback(ERR_OK); + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts new file mode 100644 index 0000000000000000000000000000000000000000..d6b1cfe4f50eaef190429094e34acfaedce1bf39 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {processDataCallback} from "./i_idl_service_ext"; +import {insertDataToMapCallback} from "./i_idl_service_ext"; +import IIdlServiceExt from "./i_idl_service_ext"; +import rpc from "@ohos.rpc"; + +export default class IdlServiceExtProxy implements IIdlServiceExt { + constructor(proxy) { + this.proxy = proxy; + } + + processData(data: number, callback: processDataCallback): void + { + let _option = new rpc.MessageOption(); + let _data = new rpc.MessageParcel(); + let _reply = new rpc.MessageParcel(); + _data.writeInt(data); + this.proxy.sendMessageRequest(IdlServiceExtProxy.COMMAND_PROCESS_DATA, _data, _reply, _option).then(function(result) { + if (result.errCode === 0) { + let _errCode = result.reply.readInt(); + if (_errCode != 0) { + let _returnValue = undefined; + callback(_errCode, _returnValue); + return; + } + let _returnValue = result.reply.readInt(); + callback(_errCode, _returnValue); + } else { + console.log("sendMessageRequest failed, errCode: " + result.errCode); + } + }) + } + + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void + { + let _option = new rpc.MessageOption(); + let _data = new rpc.MessageParcel(); + let _reply = new rpc.MessageParcel(); + _data.writeString(key); + _data.writeInt(val); + this.proxy.sendMessageRequest(IdlServiceExtProxy.COMMAND_INSERT_DATA_TO_MAP, _data, _reply, _option).then(function(result) { + if (result.errCode === 0) { + let _errCode = result.reply.readInt(); + callback(_errCode); + } else { + console.log("sendMessageRequest failed, errCode: " + result.errCode); + } + }) + } + + static readonly COMMAND_PROCESS_DATA = 1; + static readonly COMMAND_INSERT_DATA_TO_MAP = 2; + private proxy +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts new file mode 100644 index 0000000000000000000000000000000000000000..af481a1697d59e2e2e7ee67b064d9a6b42c541bb --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {processDataCallback} from "./i_idl_service_ext"; +import {insertDataToMapCallback} from "./i_idl_service_ext"; +import IIdlServiceExt from "./i_idl_service_ext"; +import rpc from "@ohos.rpc"; + +export default class IdlServiceExtStub extends rpc.RemoteObject implements IIdlServiceExt { + constructor(des: string) { + super(des); + } + + async onRemoteMessageRequest(code: number, data, reply, option): Promise { + console.log("onRemoteMessageRequest called, code = " + code); + switch(code) { + case IdlServiceExtStub.COMMAND_PROCESS_DATA: { + let _data = data.readInt(); + this.processData(_data, (errCode, returnValue) => { + reply.writeInt(errCode); + if (errCode == 0) { + reply.writeInt(returnValue); + } + }); + return true; + } + case IdlServiceExtStub.COMMAND_INSERT_DATA_TO_MAP: { + let _key = data.readString(); + let _val = data.readInt(); + this.insertDataToMap(_key, _val, (errCode) => { + reply.writeInt(errCode); + }); + return true; + } + default: { + console.log("invalid request code" + code); + break; + } + } + return false; + } + + processData(data: number, callback: processDataCallback): void{} + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void{} + + static readonly COMMAND_PROCESS_DATA = 1; + static readonly COMMAND_INSERT_DATA_TO_MAP = 2; +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/entryability/EntryAbility.ets b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..078a52eb8bb31b173c165c608ea399eaa4455d72 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Extension.ets b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Extension.ets new file mode 100644 index 0000000000000000000000000000000000000000..4b2ee4d0244a2f2da7822c45a9c5173558e73eca --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Extension.ets @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; + +let storage = LocalStorage.getShared(); +const TAG: string = '[testTag] ExtensionPage' + +@Entry(storage) +@Component +struct Extension { + @State message: string = 'UIExtension Provider'; + private session: UIExtensionContentSession | undefined = storage.get('session'); + + onPageShow() { + console.info(TAG, 'show'); + // if u wanna use setReceiveDataCallback, you should be a system app. + // this.session?.setReceiveDataCallback((data) => { + // this.message = JSON.stringify(data); + // }) + } + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(20) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + + Button("send data") + .width('80%') + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .onClick(() => { + this.session?.sendData({ "data": 543321 }); + }) + + Button("terminate self") + .width('80%') + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .onClick(() => { + this.session?.terminateSelf(); + storage.clear(); + }) + + Button("terminate self with result") + .width('80%') + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .onClick(() => { + this.session?.terminateSelfWithResult({ + resultCode: 0, + want: { + bundleName: "com.ohos.uiextensionprovider", + parameters: { "result": 123456 } + } + }) + }) + } + } + .height('100%') + } +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Index.ets b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..c0e40e0d3a9e577ef8612c49a3f14d2e097bc45b --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Entry +@Component +struct Index { + @State message: string = 'UIExtension MainPage'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(30) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/uiextensionability/UIExtensionAbility.ets b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/uiextensionability/UIExtensionAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a8a1405ca36e90ffba92d8dd5d7262638636a2a --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/ets/uiextensionability/UIExtensionAbility.ets @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import UIExtensionAbility from '@ohos.app.ability.UIExtensionAbility' +import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; +import Want from '@ohos.app.ability.Want'; +import ServiceExtImpl from '../IdlServiceExt/idl_service_ext_impl'; + +const TAG: string = '[testTag] UIExtAbility'; + +export default class UIExtAbility extends UIExtensionAbility { + serviceExtImpl = new ServiceExtImpl("ExtImpl"); + onCreate() { + console.log(TAG, `onCreate`); + } + + onForeground() { + console.log(TAG, `onForeground`); + } + + onBackground() { + console.log(TAG, `onBackground`); + } + + onDestroy() { + console.log(TAG, `onDestroy`); + } + + onSessionCreate(want: Want, session: UIExtensionContentSession) { + console.log(TAG, `onSessionCreate, want: ${JSON.stringify(want)}`); + let storage: LocalStorage = new LocalStorage(); + storage.setOrCreate('session', session); + session.loadContent('pages/Extension', storage); + } + + onSessionDestroy(session: UIExtensionContentSession) { + console.log(TAG, `onSessionDestroy`); + } + + // just for test connect ui extension ability + onConnect(want: Want) { + console.log(TAG, `onConnect, want: ${JSON.stringify(want)}`); + return this.serviceExtImpl; + } + + onDisConnect(want: Want) { + console.log(TAG, `onDisConnect, want: ${JSON.stringify(want)}`); + } +}; \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/module.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..2adb8dedbafa5b2797ad9d5d15730c600eecfc33 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/module.json @@ -0,0 +1,48 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "UIExtensionProvider", + "srcEntry": "./ets/uiextensionability/UIExtensionAbility.ets", + "description": "$string:UIExtensionAbility_desc", + "label": "$string:UIExtensionAbility_label", + "type": "sys/commonUI", + "exported": true + } + ] + } +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/color.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/string.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..8c40e6e7a04d3c78973feb371dd9bcafbc59a391 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/element/string.json @@ -0,0 +1,24 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + }, + { + "name": "UIExtensionAbility_desc", + "value": "description" + }, + { + "name": "UIExtensionAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/icon.png b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/icon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/startIcon.png b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/media/startIcon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/profile/main_pages.json b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..363b79bdaba6bd433638a0635564d7aa635be55c --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,6 @@ +{ + "src": [ + "pages/Index", + "pages/Extension" + ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/signature/openharmony_sx.p7b b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/signature/openharmony_sx.p7b new file mode 100644 index 0000000000000000000000000000000000000000..8b3a30ef5dfec0780b78cdf8b303a98dc9743f56 Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_provider_bundle/signature/openharmony_sx.p7b differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/app.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/app.json new file mode 100644 index 0000000000000000000000000000000000000000..1c12e211dad38359fedb201a9e5e9507ccbfaa1e --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/app.json @@ -0,0 +1,12 @@ +{ + "app": { + "bundleName": "com.ohos.uiextensionuser", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "minAPIVersion": 10, + "targetAPIVersion": 10 + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/element/string.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..05e001635d51f82e4f15168b3b556e5850eef2ca --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "UIExtensionUser" + } + ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/media/app_icon.png b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/AppScope/resources/base/media/app_icon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/BUILD.gn b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b17f82f47c40a96b69b1769292cdacf8782738aa --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_hap("ui_extension_user_hap") { + hap_profile = "entry/src/main/module.json" + + deps = [ + ":ui_extension_user_js_assets", + ":ui_extension_user_resources", + ] + + ets2abc = true + certificate_profile = "signature/openharmony_sx.p7b" + hap_name = "ui_extension_user" + subsystem_name = "ability" + part_name = "ability_runtime" + final_hap_path = "$root_out_dir/tests/moduletest/ability_runtime/ui_extension/resource/${hap_name}.hap" +} + +ohos_js_assets("ui_extension_user_js_assets") { + hap_profile = "entry/src/main/module.json" + source_dir = "entry/src/main/ets" +} + +ohos_app_scope("ui_extension_user_app_profile") { + app_profile = "AppScope/app.json" + sources = [ "AppScope/resources" ] +} + +ohos_resources("ui_extension_user_resources") { + sources = [ "entry/src/main/resources" ] + deps = [ ":ui_extension_user_app_profile" ] + hap_profile = "entry/src/main/module.json" +} + +group("assisthap") { + testonly = true + deps = [ ":ui_extension_user_hap" ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/entryability/EntryAbility.ets b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..078a52eb8bb31b173c165c608ea399eaa4455d72 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/pages/Index.ets b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..09e0cdc96dac392e6f81d754cdea36eaa74ae356 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Entry +@Component +struct Index { + @State message: string = 'UIExtension User'; + private myProxy: UIExtensionProxy | undefined = undefined; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(30) + .size({ width: '100%', height: '50' }) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + + UIExtensionComponent( + { + bundleName: 'com.ohos.uiextensionprovider', + abilityName: 'UIExtensionProvider', + moduleName: 'entry', + parameters: { + 'ability.want.params.uiExtensionType': 'sys/commonUI', + } + }) + .onRemoteReady((proxy) => { + this.myProxy = proxy; + }) + .onReceive((data) => { + this.message = JSON.stringify(data); + }) + .onResult((data) => { + this.message = JSON.stringify(data); + }) + .onRelease((code) => { + this.message = "release code: " + code; + }) + .offset({ x: 0, y: 30 }) + .size({ width: 300, height: 300 }) + .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) + + Button("sendData") + .type(ButtonType.Capsule) + .offset({ x: 0, y: 60 }) + .width('80%') + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .onClick(() => { + this.myProxy?.send({ + "data": 123456, + "message": "data from component" + }) + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/module.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..6c07d9d8839ac9716809c6e06c21805d52c138fe --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/module.json @@ -0,0 +1,38 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/color.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/string.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/icon.png b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/icon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/startIcon.png b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/media/startIcon.png differ diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/profile/main_pages.json b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/signature/openharmony_sx.p7b b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/signature/openharmony_sx.p7b new file mode 100644 index 0000000000000000000000000000000000000000..21fc995207a3c10b5c583dcaecdfde565cb9410a Binary files /dev/null and b/test/moduletest/ui_extension_ability_test/ui_extension_user_bundle/signature/openharmony_sx.p7b differ