From 58f57216f612a0170ffffb4124553ff1752f8a2a Mon Sep 17 00:00:00 2001 From: "zhangyafei.echo" Date: Sat, 18 Nov 2023 17:19:18 +0800 Subject: [PATCH] Description:Support connect uiextensionability. Sig:SIG_ApplicationFramework Feature or BugFix: Feature Binary Source: No Signed-off-by: zhangyafei.echo Change-Id: I4b452cadf66f79fb016a459bd1ebe6dbaea59092 --- .../native/extension_ability_thread.cpp | 2 +- interfaces/inner_api/ability_manager/BUILD.gn | 1 + .../include/ability_manager_client.h | 4 +- .../include/ability_manager_interface.h | 6 +- .../ui_extension_ability_connect_info.h | 37 +++++ services/abilitymgr/abilitymgr.gni | 1 + .../include/ability_connect_manager.h | 16 +- .../include/ability_manager_proxy.h | 3 +- .../include/ability_manager_service.h | 6 +- services/abilitymgr/include/ability_record.h | 5 +- .../ui_extension_ability_connect_manager.h | 80 ++++++++++ .../include/ui_extension_ability_record.h | 43 ++++++ .../src/ability_connect_manager.cpp | 145 +++++++++++++++--- .../abilitymgr/src/ability_manager_client.cpp | 4 +- .../abilitymgr/src/ability_manager_proxy.cpp | 24 ++- .../src/ability_manager_service.cpp | 25 ++- .../abilitymgr/src/ability_manager_stub.cpp | 12 +- services/abilitymgr/src/ability_record.cpp | 10 ++ .../src/ui_extension_ability_connect_info.cpp | 58 +++++++ .../ui_extension_ability_connect_manager.cpp | 90 +++++++++++ .../common/include/permission_constants.h | 1 + test/unittest/BUILD.gn | 1 + .../ui_extension_ability_test/BUILD.gn | 18 +++ .../ui_extension_connect_test/BUILD.gn | 53 +++++++ .../ui_extension_connect_test.cpp | 101 ++++++++++++ 25 files changed, 706 insertions(+), 40 deletions(-) create mode 100644 interfaces/inner_api/ability_manager/include/ui_extension_ability_connect_info.h create mode 100644 services/abilitymgr/include/ui_extension_ability_connect_manager.h create mode 100644 services/abilitymgr/include/ui_extension_ability_record.h create mode 100644 services/abilitymgr/src/ui_extension_ability_connect_info.cpp create mode 100644 services/abilitymgr/src/ui_extension_ability_connect_manager.cpp create mode 100644 test/unittest/ui_extension_ability_test/BUILD.gn create mode 100644 test/unittest/ui_extension_ability_test/ui_extension_connect_test/BUILD.gn create mode 100644 test/unittest/ui_extension_ability_test/ui_extension_connect_test/ui_extension_connect_test.cpp diff --git a/frameworks/native/ability/native/extension_ability_thread.cpp b/frameworks/native/ability/native/extension_ability_thread.cpp index 2846270fa2b..0ee36dd93d0 100644 --- a/frameworks/native/ability/native/extension_ability_thread.cpp +++ b/frameworks/native/ability/native/extension_ability_thread.cpp @@ -500,7 +500,7 @@ void ExtensionAbilityThread::ScheduleInsightIntentInner(const Want &want) void ExtensionAbilityThread::ScheduleCommandAbilityWindow( const Want &want, const sptr &sessionInfo, AAFwk::WindowCommand winCmd) { - HILOG_DEBUG("Begin."); + HILOG_DEBUG("Begin, winCmd: %{public}d.", winCmd); if (abilityHandler_ == nullptr) { HILOG_ERROR("abilityHandler_ is nullptr."); return; diff --git a/interfaces/inner_api/ability_manager/BUILD.gn b/interfaces/inner_api/ability_manager/BUILD.gn index e692bafc919..44ae12861a9 100644 --- a/interfaces/inner_api/ability_manager/BUILD.gn +++ b/interfaces/inner_api/ability_manager/BUILD.gn @@ -98,6 +98,7 @@ ohos_shared_library("ability_manager") { "${ability_runtime_services_path}/abilitymgr/src/stop_user_callback_proxy.cpp", "${ability_runtime_services_path}/abilitymgr/src/stop_user_callback_stub.cpp", "${ability_runtime_services_path}/abilitymgr/src/system_ability_token_callback_stub.cpp", + "${ability_runtime_services_path}/abilitymgr/src/ui_extension_ability_connect_info.cpp", "${ability_runtime_services_path}/abilitymgr/src/want_receiver_stub.cpp", "${ability_runtime_services_path}/abilitymgr/src/want_sender_info.cpp", "${ability_runtime_services_path}/abilitymgr/src/want_sender_proxy.cpp", diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_client.h b/interfaces/inner_api/ability_manager/include/ability_manager_client.h index e7d486497f4..9c97aa77902 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -436,10 +436,12 @@ public: * @param connect, callback used to notify caller the result of connecting or disconnecting. * @param sessionInfo the extension session info of the ability to connect. * @param userId, the extension runs in. + * @param connectInfo the connect info. * @return Returns ERR_OK on success, others on failure. */ ErrCode ConnectUIExtensionAbility(const Want &want, sptr connect, - sptr sessionInfo, int32_t userId = DEFAULT_INVAL_VALUE); + sptr sessionInfo, int32_t userId = DEFAULT_INVAL_VALUE, + sptr connectInfo = nullptr); /** * DisconnectAbility, disconnect session with service ability. diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h index 142d27a09fb..0aa7ed60912 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -48,6 +48,7 @@ #include "start_options.h" #include "stop_user_callback.h" #include "system_memory_attr.h" +#include "ui_extension_ability_connect_info.h" #include "ui_extension_window_command.h" #include "uri.h" #include "want.h" @@ -63,6 +64,7 @@ namespace AAFwk { using AutoStartupInfo = AbilityRuntime::AutoStartupInfo; using InsightIntentExecuteParam = AppExecFwk::InsightIntentExecuteParam; using InsightIntentExecuteResult = AppExecFwk::InsightIntentExecuteResult; +using UIExtensionAbilityConnectInfo = AbilityRuntime::UIExtensionAbilityConnectInfo; constexpr const char* ABILITY_MANAGER_SERVICE_NAME = "AbilityManagerService"; const int DEFAULT_INVAL_VALUE = -1; const int DELAY_LOCAL_FREE_INSTALL_TIMEOUT = 40000; @@ -465,10 +467,12 @@ public: * @param connect, callback used to notify caller the result of connecting or disconnecting. * @param sessionInfo the extension session info of the ability to connect. * @param userId, the extension runs in. + * @param connectInfo the connect info. * @return Returns ERR_OK on success, others on failure. */ virtual int ConnectUIExtensionAbility(const Want &want, const sptr &connect, - const sptr &sessionInfo, int32_t userId = DEFAULT_INVAL_VALUE) + const sptr &sessionInfo, int32_t userId = DEFAULT_INVAL_VALUE, + sptr connectInfo = nullptr) { return 0; } diff --git a/interfaces/inner_api/ability_manager/include/ui_extension_ability_connect_info.h b/interfaces/inner_api/ability_manager/include/ui_extension_ability_connect_info.h new file mode 100644 index 00000000000..f86f692d7c8 --- /dev/null +++ b/interfaces/inner_api/ability_manager/include/ui_extension_ability_connect_info.h @@ -0,0 +1,37 @@ +/* + * 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_ABILITY_CONNECT_INFO_H +#define OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_CONNECT_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace AbilityRuntime { +class UIExtensionAbilityConnectInfo : public Parcelable { +public: + UIExtensionAbilityConnectInfo() = default; + virtual ~UIExtensionAbilityConnectInfo() = default; + + bool ReadFromParcel(Parcel &parcel); + bool Marshalling(Parcel &parcel) const override; + static UIExtensionAbilityConnectInfo *Unmarshalling(Parcel &parcel); + + std::string hostBundleName = ""; // The bundleName of uiextensionability user. + int32_t uiExtensionAbilityId = 0; // The uiextensionability id. +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_CONNECT_INFO_H diff --git a/services/abilitymgr/abilitymgr.gni b/services/abilitymgr/abilitymgr.gni index 6298238c2a1..feb25f2e200 100644 --- a/services/abilitymgr/abilitymgr.gni +++ b/services/abilitymgr/abilitymgr.gni @@ -62,6 +62,7 @@ abilityms_files = [ # new ability manager service here "src/task_data_persistence_mgr.cpp", + "src/ui_extension_ability_connect_manager.cpp", "src/start_options.cpp", "src/stop_user_callback_proxy.cpp", "src/stop_user_callback_stub.cpp", diff --git a/services/abilitymgr/include/ability_connect_manager.h b/services/abilitymgr/include/ability_connect_manager.h index 074a68fa3ba..ed4bbd31a4e 100644 --- a/services/abilitymgr/include/ability_connect_manager.h +++ b/services/abilitymgr/include/ability_connect_manager.h @@ -31,6 +31,8 @@ #include "extension_running_info.h" #include "connection_record.h" #include "element_name.h" +#include "ui_extension_ability_connect_info.h" +#include "ui_extension_ability_connect_manager.h" #include "want.h" #include "iremote_object.h" #include "nocopyable.h" @@ -38,6 +40,9 @@ namespace OHOS { namespace AAFwk { using OHOS::AppExecFwk::AbilityType; +using UIExtensionAbilityConnectInfo = AbilityRuntime::UIExtensionAbilityConnectInfo; +using UIExtensionAbilityConnectManager = AbilityRuntime::UIExtensionAbilityConnectManager; + /** * @class AbilityConnectManager * AbilityConnectManager provides a facility for managing service ability connection. @@ -87,10 +92,12 @@ public: * @param connect, Callback used to notify caller the result of connecting or disconnecting. * @param callerToken, caller ability token. * @param sessionInfo the extension session info of the ability to connect. + * @param connectInfo the connect info. * @return Returns ERR_OK on success, others on failure. */ int ConnectAbilityLocked(const AbilityRequest &abilityRequest, const sptr &connect, - const sptr &callerToken, sptr sessionInfo = nullptr); + const sptr &callerToken, sptr sessionInfo = nullptr, + sptr connectInfo = nullptr); /** * DisconnectAbilityLocked, disconnect session with callback. @@ -495,6 +502,12 @@ private: bool IsLauncher(std::shared_ptr serviceExtension) const; bool IsSceneBoard(std::shared_ptr serviceExtension) const; void KillProcessesByUserId() const; + inline bool IsUIExtensionAbility(const std::shared_ptr abilityRecord); + inline bool CheckUIExtensionAbilityLoaded(const AbilityRequest &abilityRequest); + inline bool CheckUIExtensionAbilitySessionExistLocked(const std::shared_ptr abilityRecord); + inline int32_t AddUIExtensionAbilityRecord(const std::shared_ptr abilityRecord, + const std::string hostBundleName, const int32_t inputId) const; + inline void RemoveUIExtensionAbilityRecord(const std::shared_ptr abilityRecord); private: const std::string TASK_ON_CALLBACK_DIED = "OnCallbackDiedTask"; @@ -514,6 +527,7 @@ private: ffrt::mutex startServiceReqListLock_; UIExtensionMapType uiExtensionMap_; WindowExtensionMapType windowExtensionMap_; + std::unique_ptr uiExtensionAbilityRecordMgr_ = nullptr; DISALLOW_COPY_AND_MOVE(AbilityConnectManager); }; diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 78f2fe3901b..bf88a47c108 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -347,7 +347,8 @@ public: const Want &want, const sptr &connect, const sptr &sessionInfo, - int32_t userId = DEFAULT_INVAL_VALUE) override; + int32_t userId = DEFAULT_INVAL_VALUE, + sptr connectInfo = nullptr) override; /** * DisconnectAbility, connect session with service ability. diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index c916cc53408..7bdff6ce9a7 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -404,7 +404,8 @@ public: const Want &want, const sptr &connect, const sptr &sessionInfo, - int32_t userId = DEFAULT_INVAL_VALUE) override; + int32_t userId = DEFAULT_INVAL_VALUE, + sptr connectInfo = nullptr) override; /** * ContinueMission, continue ability from mission center. @@ -1516,7 +1517,8 @@ private: const sptr &callerToken, AppExecFwk::ExtensionAbilityType extensionType, const sptr &sessionInfo = nullptr, - bool isQueryExtensionOnly = false); + bool isQueryExtensionOnly = false, + sptr connectInfo = nullptr); int DisconnectLocalAbility(const sptr &connect); int ConnectRemoteAbility(Want &want, const sptr &callerToken, const sptr &connect); int DisconnectRemoteAbility(const sptr &connect); diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 07fed2eab88..cafa7af4d90 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -920,6 +920,9 @@ public: void SetAbilityWindowState(const sptr &sessionInfo, WindowCommand winCmd, bool isFinished); + void SetUIExtensionAbilityId(const int32_t uiExtensionAbilityId); + int32_t GetUIExtensionAbilityId() const; + protected: void SendEvent(uint32_t msg, uint32_t timeOut, int32_t param = -1); @@ -1004,6 +1007,7 @@ private: static int64_t abilityRecordId; int recordId_ = 0; // record id + int32_t uiExtensionAbilityId_ = 0; // uiextension ability id AppExecFwk::AbilityInfo abilityInfo_ = {}; // the ability info get from BMS AppExecFwk::ApplicationInfo applicationInfo_ = {}; // the ability info get from BMS std::weak_ptr preAbilityRecord_ = {}; // who starts this ability record @@ -1090,7 +1094,6 @@ private: // scene session sptr sessionInfo_ = nullptr; - std::unordered_set sessionIds_; std::map abilityWindowStateMap_; diff --git a/services/abilitymgr/include/ui_extension_ability_connect_manager.h b/services/abilitymgr/include/ui_extension_ability_connect_manager.h new file mode 100644 index 00000000000..2b6e8d00613 --- /dev/null +++ b/services/abilitymgr/include/ui_extension_ability_connect_manager.h @@ -0,0 +1,80 @@ +/* + * 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_ABILITY_CONNECT_MANAGER_H +#define OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_CONNECT_MANAGER_H + +#include +#include +#include +#include + +#include "ui_extension_ability_record.h" + +namespace OHOS { +namespace AbilityRuntime { +constexpr int32_t INVALID_UI_EXTENSION_ABILITY_ID = 0; + +class UIExtensionAbilityConnectManager : public std::enable_shared_from_this { +public: + using UIExtensionAbilityRecordMap = std::map>; + + explicit UIExtensionAbilityConnectManager(const int32_t userId); + virtual ~UIExtensionAbilityConnectManager(); + + /** + * @brief Generate uiextensionability id, if input id didn't exist, return it, else assign one. + * + * @param uiExtensionAbilityId Input uiextensionability id. + * @return int32_t Generated uiextensionability id. + */ + int32_t GenerateUIExtensionAbilityId(const int32_t uiExtensionAbilityId); + + /** + * @brief Add uiextensionability record by id, if record exist, replace it. + * + * @param uiExtensionAbilityId uiextensionability id. + * @param record uiextensionability record. + */ + void AddUIExtensionAbilityRecord(const int32_t uiExtensionAbilityId, + const std::shared_ptr record); + + /** + * @brief Remove uiextensionability record by id + * + * @param uiExtensionAbilityId uiextensionability id. + */ + void RemoveUIExtensionAbilityRecord(const int32_t uiExtensionAbilityId); + + /** + * @brief Check if host bundleName matched to stored record by specified id. + * + * @param uiExtensionAbilityId uiextensionability id. + * @param hostBundleName bundleName of target uiextensionability. + * @return true Matched. + * @return false Not Match. + */ + bool CheckUIExtensionAbilityLoaded(const int32_t uiExtensionAbilityId, const std::string hostBundleName); + +private: + int32_t userId_; + static std::atomic_int32_t uiExtensionAbilityId_; + std::mutex mutex_; + std::set uiExtensionAbilityIdSet_; + UIExtensionAbilityRecordMap uiExtensionAbilityRecords_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_CONNECT_MANAGER_H diff --git a/services/abilitymgr/include/ui_extension_ability_record.h b/services/abilitymgr/include/ui_extension_ability_record.h new file mode 100644 index 00000000000..dd5e11b912d --- /dev/null +++ b/services/abilitymgr/include/ui_extension_ability_record.h @@ -0,0 +1,43 @@ +/* + * 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_ABILITY_RECORD_H +#define OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_RECORD_H + +#include +#include +#include +#include + +#include "ability_record.h" + +namespace OHOS { +namespace AbilityRuntime { +class UIExtensionAbilityRecord : public std::enable_shared_from_this { +public: + UIExtensionAbilityRecord(const std::shared_ptr abilityRecord, std::string hostBundleName, + int32_t uiExtensionAbilityId) + : abilityRecord_(abilityRecord), hostBundleName_(hostBundleName), uiExtensionAbilityId_(uiExtensionAbilityId) + {} + + virtual ~UIExtensionAbilityRecord() = default; + + std::shared_ptr abilityRecord_ = nullptr; + std::string hostBundleName_ = ""; + int32_t uiExtensionAbilityId_ = 0; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_UI_EXTENSION_ABILITY_RECORD_H diff --git a/services/abilitymgr/src/ability_connect_manager.cpp b/services/abilitymgr/src/ability_connect_manager.cpp index c1f93259c27..e8dabf4839a 100644 --- a/services/abilitymgr/src/ability_connect_manager.cpp +++ b/services/abilitymgr/src/ability_connect_manager.cpp @@ -30,6 +30,7 @@ #include "mock_session_manager_service.h" #include "parameter.h" #include "session/host/include/zidl/session_interface.h" +#include "ui_extension_ability_record.h" #include "ui_extension_utils.h" namespace OHOS { @@ -41,6 +42,7 @@ constexpr char EVENT_KEY_MESSAGE[] = "MSG"; constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME"; constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME"; const std::string DEBUG_APP = "debugApp"; +const std::string UIEXTENSION_ABILITY_ID = "ability.want.params.uiExtensionAbilityId"; #ifdef SUPPORT_ASAN const int LOAD_TIMEOUT_MULTIPLE = 150; const int CONNECT_TIMEOUT_MULTIPLE = 45; @@ -64,7 +66,9 @@ const std::unordered_set FROZEN_WHITE_LIST { } AbilityConnectManager::AbilityConnectManager(int userId) : userId_(userId) -{} +{ + uiExtensionAbilityRecordMgr_ = std::make_unique(userId); +} AbilityConnectManager::~AbilityConnectManager() {} @@ -85,6 +89,13 @@ int AbilityConnectManager::TerminateAbility(const sptr &token) int AbilityConnectManager::TerminateAbilityInner(const sptr &token) { auto abilityRecord = GetExtensionFromServiceMapInner(token); + CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE); + std::string element = abilityRecord->GetElementName().GetURI(); + HILOG_DEBUG("Terminate ability, ability is %{public}s.", element.c_str()); + if (IsUIExtensionAbility(abilityRecord) && !abilityRecord->IsConnectListEmpty()) { + HILOG_INFO("There exist connection, don't terminate."); + return ERR_OK; + } MoveToTerminatingMap(abilityRecord); return TerminateAbilityLocked(token); } @@ -110,7 +121,7 @@ int AbilityConnectManager::StartAbilityLocked(const AbilityRequest &abilityReque targetService->SetLaunchReason(LaunchReason::LAUNCHREASON_START_EXTENSION); - if (UIExtensionUtils::IsUIExtension(targetService->GetAbilityInfo().extensionAbilityType) + if (IsUIExtensionAbility(targetService) && abilityRequest.sessionInfo && abilityRequest.sessionInfo->sessionToken) { auto &remoteObj = abilityRequest.sessionInfo->sessionToken; uiExtensionMap_[remoteObj] = UIExtWindowMapValType(targetService, abilityRequest.sessionInfo); @@ -120,14 +131,22 @@ int AbilityConnectManager::StartAbilityLocked(const AbilityRequest &abilityReque if (!isLoadedAbility) { HILOG_INFO("Target service has not been loaded."); LoadAbility(targetService); - } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) { + if (IsUIExtensionAbility(targetService) && abilityRequest.sessionInfo != nullptr) { + std::string hostBundleName = abilityRequest.abilityInfo.bundleName; + int32_t inputId = abilityRequest.sessionInfo->want.GetIntParam(UIEXTENSION_ABILITY_ID, + INVALID_UI_EXTENSION_ABILITY_ID); + auto uiExtensionAbilityId = AddUIExtensionAbilityRecord(targetService, hostBundleName, inputId); + HILOG_DEBUG("UIExtensionAbility id %{public}d.", uiExtensionAbilityId); + } + } else if (targetService->IsAbilityState(AbilityState::ACTIVE) && !IsUIExtensionAbility(targetService)) { // It may have been started through connect targetService->SetWant(abilityRequest.want); CommandAbility(targetService); - } else if (UIExtensionUtils::IsUIExtension(targetService->GetAbilityInfo().extensionAbilityType) - && targetService->IsReady() && !targetService->IsAbilityState(AbilityState::INACTIVATING) - && !targetService->IsAbilityState(AbilityState::BACKGROUNDING) - && targetService->IsAbilityWindowReady()) { + } else if (IsUIExtensionAbility(targetService) && + targetService->IsReady() && !targetService->IsAbilityState(AbilityState::INACTIVATING) && + !targetService->IsAbilityState(AbilityState::BACKGROUNDING) && + targetService->IsAbilityWindowReady() && + CheckUIExtensionAbilityLoaded(abilityRequest)) { targetService->SetWant(abilityRequest.want); CommandAbilityWindow(targetService, abilityRequest.sessionInfo, WIN_CMD_FOREGROUND); } else { @@ -196,6 +215,7 @@ int AbilityConnectManager::TerminateAbilityLocked(const sptr &tok connectManager->HandleStopTimeoutTask(abilityRecord); }; abilityRecord->Terminate(timeoutTask); + RemoveUIExtensionAbilityRecord(abilityRecord); return ERR_OK; } @@ -232,6 +252,7 @@ void AbilityConnectManager::GetOrCreateServiceRecord(const AbilityRequest &abili bool noReuse = UIExtensionUtils::IsWindowExtension(abilityRequest.abilityInfo.extensionAbilityType); AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName); + HILOG_DEBUG("Service map element is %{public}s.", element.GetURI().c_str()); auto serviceMapIter = serviceMap_.find(element.GetURI()); if (noReuse && serviceMapIter != serviceMap_.end()) { serviceMap_.erase(element.GetURI()); @@ -273,7 +294,8 @@ void AbilityConnectManager::GetConnectRecordListFromMap( } int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityRequest, - const sptr &connect, const sptr &callerToken, sptr sessionInfo) + const sptr &connect, const sptr &callerToken, sptr sessionInfo, + sptr connectInfo) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); HILOG_INFO("callee:%{public}s.", abilityRequest.want.GetElement().GetURI().c_str()); @@ -322,6 +344,12 @@ int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityReq int ret = ERR_OK; if (!isLoadedAbility) { LoadAbility(targetService); + if (IsUIExtensionAbility(targetService) && connectInfo != nullptr) { + auto uiExtensionAbilityId = AddUIExtensionAbilityRecord(targetService, connectInfo->hostBundleName, + connectInfo->uiExtensionAbilityId); + connectInfo->uiExtensionAbilityId = uiExtensionAbilityId; + HILOG_DEBUG("UIExtensionAbility id %{public}d.", connectInfo->uiExtensionAbilityId); + } } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) { // this service ability has connected already targetService->SetWant(abilityRequest.want); @@ -488,7 +516,7 @@ void AbilityConnectManager::OnAbilityRequestDone(const sptr &toke if (abilityState == AppAbilityState::ABILITY_STATE_FOREGROUND) { auto abilityRecord = GetExtensionFromServiceMapInner(token); CHECK_POINTER(abilityRecord); - if (!UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) { + if (!IsUIExtensionAbility(abilityRecord)) { HILOG_ERROR("Not ui extension."); return; } @@ -649,8 +677,15 @@ int AbilityConnectManager::ScheduleDisconnectAbilityDoneLocked(const sptrIsAbilityState(AbilityState::ACTIVE)) { - HILOG_ERROR("The service ability state is not active ,state: %{public}d", abilityRecord->GetAbilityState()); - return INVALID_CONNECTION_STATE; + if (IsUIExtensionAbility(abilityRecord) && (abilityRecord->IsForeground() || + abilityRecord->IsAbilityState(AbilityState::BACKGROUND) || + abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING))) { + // uiextension ability support connect and start, so the ability state maybe others + HILOG_INFO("Disconnect when ability state is %{public}d", abilityRecord->GetAbilityState()); + } else { + HILOG_ERROR("The service ability state is not active ,state: %{public}d", abilityRecord->GetAbilityState()); + return INVALID_CONNECTION_STATE; + } } if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) { @@ -668,8 +703,12 @@ int AbilityConnectManager::ScheduleDisconnectAbilityDoneLocked(const sptrScheduleDisconnectAbilityDone(); abilityRecord->RemoveConnectRecordFromList(connect); if (abilityRecord->IsConnectListEmpty() && abilityRecord->GetStartId() == 0) { - HILOG_INFO("Service ability has no any connection, and not started , need terminate."); - TerminateRecord(abilityRecord); + if (IsUIExtensionAbility(abilityRecord) && CheckUIExtensionAbilitySessionExistLocked(abilityRecord)) { + HILOG_INFO("There exist ui extension component, don't terminate when disconnet."); + } else { + HILOG_INFO("Service ability has no any connection, and not started, need terminate."); + TerminateRecord(abilityRecord); + } } RemoveConnectionRecordFromMap(connect); @@ -726,18 +765,20 @@ int AbilityConnectManager::ScheduleCommandAbilityWindowDone( switch (abilityCmd) { case ABILITY_CMD_FOREGROUND: { - if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) - || abilityRecord->IsAbilityState(AbilityState::BACKGROUND) - || abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING)) { + if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) || + abilityRecord->IsAbilityState(AbilityState::ACTIVE) || + abilityRecord->IsAbilityState(AbilityState::BACKGROUND) || + abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING)) { HILOG_DEBUG("Foreground %{public}s", element.c_str()); DelayedSingleton::GetInstance()->MoveToForeground(token); } break; } case ABILITY_CMD_BACKGROUND: { - if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) - || abilityRecord->IsAbilityState(AbilityState::FOREGROUND) - || abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) { + if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) || + abilityRecord->IsAbilityState(AbilityState::ACTIVE) || + abilityRecord->IsAbilityState(AbilityState::FOREGROUND) || + abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) { MoveToBackground(abilityRecord); } break; @@ -1198,7 +1239,7 @@ int AbilityConnectManager::DispatchInactive(const std::shared_ptr abilityRecord->SetAbilityState(AbilityState::INACTIVE); if (abilityRecord->IsCreateByConnect()) { ConnectAbility(abilityRecord); - } else if (UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) { + } else if (IsUIExtensionAbility(abilityRecord)) { CommandAbilityWindow(abilityRecord, abilityRecord->GetSessionInfo(), WIN_CMD_FOREGROUND); } else { CommandAbility(abilityRecord); @@ -1632,7 +1673,7 @@ void AbilityConnectManager::HandleAbilityDiedTask( return; } - if (UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) { + if (IsUIExtensionAbility(abilityRecord)) { HandleUIExtensionDied(abilityRecord); } @@ -2239,5 +2280,67 @@ void AbilityConnectManager::HandleExtensionDisconnectTask(const std::shared_ptr< RemoveConnectionRecordFromMap(connectRecord); } } + +bool AbilityConnectManager::IsUIExtensionAbility(const std::shared_ptr abilityRecord) +{ + CHECK_POINTER_AND_RETURN(abilityRecord, false); + return UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType); +} + +bool AbilityConnectManager::CheckUIExtensionAbilityLoaded(const AbilityRequest &abilityRequest) +{ + CHECK_POINTER_AND_RETURN(abilityRequest.sessionInfo, false); + CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, false); + + int32_t uiExtensionAbilityId = abilityRequest.sessionInfo->want.GetIntParam(UIEXTENSION_ABILITY_ID, + INVALID_UI_EXTENSION_ABILITY_ID); + if (uiExtensionAbilityId == INVALID_UI_EXTENSION_ABILITY_ID) { + HILOG_DEBUG("Didn't carry uiextension ability id when start."); + return true; + } + + auto ret = uiExtensionAbilityRecordMgr_->CheckUIExtensionAbilityLoaded( + uiExtensionAbilityId, abilityRequest.abilityInfo.bundleName); + HILOG_DEBUG("UIExtensionAbility loaded status: %{public}s.", ret ? "true" : "false"); + return ret; +} + +bool AbilityConnectManager::CheckUIExtensionAbilitySessionExistLocked( + const std::shared_ptr abilityRecord) +{ + CHECK_POINTER_AND_RETURN(abilityRecord, false); + + for (auto it = uiExtensionMap_.begin(); it != uiExtensionMap_.end();) { + std::shared_ptr uiExtAbility = it->second.first.lock(); + if (abilityRecord == uiExtAbility) { + return true; + } + it++; + } + + return false; +} + +int32_t AbilityConnectManager::AddUIExtensionAbilityRecord(const std::shared_ptr abilityRecord, + const std::string hostBundleName, const int32_t inputId) const +{ + CHECK_POINTER_AND_RETURN(abilityRecord, INVALID_UI_EXTENSION_ABILITY_ID); + CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, INVALID_UI_EXTENSION_ABILITY_ID); + + auto uiExtensionAbilityId = uiExtensionAbilityRecordMgr_->GenerateUIExtensionAbilityId(inputId); + HILOG_DEBUG("Generated id is %{public}d.", uiExtensionAbilityId); + abilityRecord->SetUIExtensionAbilityId(uiExtensionAbilityId); + auto uiExtensionAbilityRecord = std::make_shared(abilityRecord, + hostBundleName, uiExtensionAbilityId); + uiExtensionAbilityRecordMgr_->AddUIExtensionAbilityRecord(uiExtensionAbilityId, uiExtensionAbilityRecord); + return uiExtensionAbilityId; +} + +void AbilityConnectManager::RemoveUIExtensionAbilityRecord(const std::shared_ptr abilityRecord) +{ + CHECK_POINTER(abilityRecord); + CHECK_POINTER(uiExtensionAbilityRecordMgr_); + uiExtensionAbilityRecordMgr_->RemoveUIExtensionAbilityRecord(abilityRecord->GetUIExtensionAbilityId()); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index cecda0e7e90..13b408044c8 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -433,7 +433,7 @@ ErrCode AbilityManagerClient::ConnectExtensionAbility(const Want &want, sptr connect, - sptr sessionInfo, int32_t userId) + sptr sessionInfo, int32_t userId, sptr connectInfo) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); auto abms = GetAbilityManager(); @@ -447,7 +447,7 @@ ErrCode AbilityManagerClient::ConnectUIExtensionAbility(const Want &want, sptrConnectUIExtensionAbility(want, connect, sessionInfo, userId); + return abms->ConnectUIExtensionAbility(want, connect, sessionInfo, userId, connectInfo); } ErrCode AbilityManagerClient::DisconnectAbility(sptr connect) diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index c84f14fbbf2..a229b6734e7 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -894,7 +894,7 @@ int AbilityManagerProxy::ConnectAbilityCommon( } int AbilityManagerProxy::ConnectUIExtensionAbility(const Want &want, const sptr &connect, - const sptr &sessionInfo, int32_t userId) + const sptr &sessionInfo, int32_t userId, sptr connectInfo) { MessageParcel data; MessageParcel reply; @@ -935,11 +935,33 @@ int AbilityManagerProxy::ConnectUIExtensionAbility(const Want &want, const sptr< HILOG_ERROR("UserId write failed."); return INNER_ERR; } + + if (connectInfo != nullptr) { + if (!data.WriteBool(true) || !data.WriteParcelable(connectInfo)) { + HILOG_ERROR("flag and connectInfo write failed."); + return ERR_INVALID_VALUE; + } + } else { + if (!data.WriteBool(false)) { + HILOG_ERROR("flag write failed."); + return ERR_INVALID_VALUE; + } + } + int error = SendRequest(AbilityManagerInterfaceCode::CONNECT_UI_EXTENSION_ABILITY, data, reply, option); if (error != NO_ERROR) { HILOG_ERROR("Send request error: %{public}d", error); return error; } + + if (connectInfo != nullptr) { + sptr replyInfo = reply.ReadParcelable(); + if (replyInfo != nullptr) { + connectInfo->uiExtensionAbilityId = replyInfo->uiExtensionAbilityId; + HILOG_DEBUG("UIExtensionAbilityId is %{public}d.", connectInfo->uiExtensionAbilityId); + } + } + return reply.ReadInt32(); } diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 1259145face..ea019775689 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -74,6 +74,7 @@ #include "string_wrapper.h" #include "system_ability_definition.h" #include "system_ability_token_callback.h" +#include "ui_extension_ability_connect_manager.h" #include "ui_extension_utils.h" #include "uri_permission_manager_client.h" #include "xcollie/watchdog.h" @@ -2938,7 +2939,7 @@ int AbilityManagerService::ConnectAbilityCommon( } int AbilityManagerService::ConnectUIExtensionAbility(const Want &want, const sptr &connect, - const sptr &sessionInfo, int32_t userId) + const sptr &sessionInfo, int32_t userId, sptr connectInfo) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); HILOG_DEBUG("Connect ui extension called, bundlename: %{public}s, ability is %{public}s, userId is %{pravite}d", @@ -3013,14 +3014,14 @@ int AbilityManagerService::ConnectUIExtensionAbility(const Want &want, const spt if (callerToken != nullptr && callerToken->GetObjectDescriptor() != u"ohos.aafwk.AbilityToken") { HILOG_INFO("%{public}s invalid Token.", __func__); eventInfo.errCode = ConnectLocalAbility(abilityWant, validUserId, connect, nullptr, - AppExecFwk::ExtensionAbilityType::UI, sessionInfo); + AppExecFwk::ExtensionAbilityType::UI, sessionInfo, false, connectInfo); if (eventInfo.errCode != ERR_OK) { EventReport::SendExtensionEvent(EventName::CONNECT_SERVICE_ERROR, HiSysEventType::FAULT, eventInfo); } return eventInfo.errCode; } eventInfo.errCode = ConnectLocalAbility(abilityWant, validUserId, connect, callerToken, - AppExecFwk::ExtensionAbilityType::UI, sessionInfo); + AppExecFwk::ExtensionAbilityType::UI, sessionInfo, false, connectInfo); if (eventInfo.errCode != ERR_OK) { EventReport::SendExtensionEvent(EventName::CONNECT_SERVICE_ERROR, HiSysEventType::FAULT, eventInfo); } @@ -3057,7 +3058,7 @@ int AbilityManagerService::DisconnectAbility(const sptr &con int AbilityManagerService::ConnectLocalAbility(const Want &want, const int32_t userId, const sptr &connect, const sptr &callerToken, AppExecFwk::ExtensionAbilityType extensionType, const sptr &sessionInfo, - bool isQueryExtensionOnly) + bool isQueryExtensionOnly, sptr connectInfo) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); HILOG_INFO("Connect local ability begin."); @@ -3111,13 +3112,23 @@ int AbilityManagerService::ConnectLocalAbility(const Want &want, const int32_t u return ERR_STATIC_CFG_PERMISSION; } + AppExecFwk::ExtensionAbilityType targetExtensionType = abilityInfo.extensionAbilityType; + HILOG_DEBUG("extension type %{public}d.", targetExtensionType); if (AAFwk::UIExtensionUtils::IsUIExtension(extensionType)) { - AppExecFwk::ExtensionAbilityType targetExtensionType = abilityInfo.extensionAbilityType; - if (targetExtensionType != AppExecFwk::ExtensionAbilityType::UI + if (!AAFwk::UIExtensionUtils::IsUIExtension(targetExtensionType) && targetExtensionType != AppExecFwk::ExtensionAbilityType::WINDOW) { HILOG_ERROR("Try to connect UI extension, but target ability is not UI extension."); return ERR_WRONG_INTERFACE_CALL; } + + // Cause window has used this api, don't check it when type is window. + if (targetExtensionType != AppExecFwk::ExtensionAbilityType::WINDOW && + !PermissionVerification::GetInstance()->VerifyCallingPermission( + PermissionConstants::PERMISSION_CONNECT_UI_EXTENSION_ABILITY)) { + HILOG_ERROR("Permission %{public}s verification failed.", + PermissionConstants::PERMISSION_CONNECT_UI_EXTENSION_ABILITY); + return ERR_PERMISSION_DENIED; + } } auto type = abilityInfo.type; @@ -3153,7 +3164,7 @@ int AbilityManagerService::ConnectLocalAbility(const Want &want, const int32_t u } ReportEventToSuspendManager(abilityInfo); - return connectManager->ConnectAbilityLocked(abilityRequest, connect, callerToken, sessionInfo); + return connectManager->ConnectAbilityLocked(abilityRequest, connect, callerToken, sessionInfo, connectInfo); } int AbilityManagerService::ConnectRemoteAbility(Want &want, const sptr &callerToken, diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index cd7cfefdaf7..9728537b1a8 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -941,7 +941,17 @@ int AbilityManagerStub::ConnectUIExtensionAbilityInner(MessageParcel &data, Mess sessionInfo = data.ReadParcelable(); } int32_t userId = data.ReadInt32(); - int32_t result = ConnectUIExtensionAbility(*want, callback, sessionInfo, userId); + + sptr connectInfo = nullptr; + if (data.ReadBool()) { + connectInfo = data.ReadParcelable(); + } + + int32_t result = ConnectUIExtensionAbility(*want, callback, sessionInfo, userId, connectInfo); + if (connectInfo != nullptr && !reply.WriteParcelable(connectInfo)) { + HILOG_ERROR("connectInfo write failed."); + } + reply.WriteInt32(result); if (want != nullptr) { delete want; diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 106bee105b6..ac7d1e1006f 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -3112,5 +3112,15 @@ int32_t AbilityRecord::CreateModalUIExtension(const Want &want) CHECK_POINTER_AND_RETURN(scheduler_, INNER_ERR); return scheduler_->CreateModalUIExtension(want); } + +void AbilityRecord::SetUIExtensionAbilityId(const int32_t uiExtensionAbilityId) +{ + uiExtensionAbilityId_ = uiExtensionAbilityId; +} + +int32_t AbilityRecord::GetUIExtensionAbilityId() const +{ + return uiExtensionAbilityId_; +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ui_extension_ability_connect_info.cpp b/services/abilitymgr/src/ui_extension_ability_connect_info.cpp new file mode 100644 index 00000000000..e1902131ed2 --- /dev/null +++ b/services/abilitymgr/src/ui_extension_ability_connect_info.cpp @@ -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. + */ + +#include "ui_extension_ability_connect_info.h" +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +bool UIExtensionAbilityConnectInfo::ReadFromParcel(Parcel &parcel) +{ + hostBundleName = parcel.ReadString(); + uiExtensionAbilityId = parcel.ReadInt32(); + return true; +} + +UIExtensionAbilityConnectInfo *UIExtensionAbilityConnectInfo::Unmarshalling(Parcel &parcel) +{ + UIExtensionAbilityConnectInfo *connectInfo = new (std::nothrow) UIExtensionAbilityConnectInfo(); + if (connectInfo == nullptr) { + HILOG_ERROR("New connect Info failed."); + return nullptr; + } + + if (!connectInfo->ReadFromParcel(parcel)) { + delete connectInfo; + connectInfo = nullptr; + } + return connectInfo; +} + +bool UIExtensionAbilityConnectInfo::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteString(hostBundleName)) { + HILOG_ERROR("Write hostBundleName failed."); + return false; + } + + if (!parcel.WriteInt32(uiExtensionAbilityId)) { + HILOG_ERROR("Write uiExtensionAbilityId failed."); + return false; + } + + return true; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/services/abilitymgr/src/ui_extension_ability_connect_manager.cpp b/services/abilitymgr/src/ui_extension_ability_connect_manager.cpp new file mode 100644 index 00000000000..57b2d6f25c1 --- /dev/null +++ b/services/abilitymgr/src/ui_extension_ability_connect_manager.cpp @@ -0,0 +1,90 @@ +/* + * 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_ability_connect_manager.h" + +#include "hilog_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +std::atomic_int32_t UIExtensionAbilityConnectManager::uiExtensionAbilityId_ = INVALID_UI_EXTENSION_ABILITY_ID; + +UIExtensionAbilityConnectManager::UIExtensionAbilityConnectManager(const int userId) : userId_(userId) +{ + HILOG_DEBUG("constructor."); +} + +UIExtensionAbilityConnectManager::~UIExtensionAbilityConnectManager() +{ + HILOG_INFO("deconstructor."); +} + +int32_t UIExtensionAbilityConnectManager::GenerateUIExtensionAbilityId(const int32_t uiExtensionAbilityId) +{ + HILOG_DEBUG("Input id is %{public}d.", uiExtensionAbilityId); + std::lock_guard lock(mutex_); + if (uiExtensionAbilityId != INVALID_UI_EXTENSION_ABILITY_ID && + !uiExtensionAbilityIdSet_.count(uiExtensionAbilityId)) { + uiExtensionAbilityIdSet_.insert(uiExtensionAbilityId); + uiExtensionAbilityId_ = uiExtensionAbilityId; + return uiExtensionAbilityId_; + } + + if (uiExtensionAbilityId == INVALID_UI_EXTENSION_ABILITY_ID) { + ++uiExtensionAbilityId_; + } + + while (uiExtensionAbilityIdSet_.count(uiExtensionAbilityId_)) { + uiExtensionAbilityId_++; + } + + return uiExtensionAbilityId_; +} + +void UIExtensionAbilityConnectManager::AddUIExtensionAbilityRecord(const int32_t uiExtensionAbilityId, + const std::shared_ptr record) +{ + HILOG_DEBUG("UIExtensionAbilityId %{public}d.", uiExtensionAbilityId); + std::lock_guard lock(mutex_); + uiExtensionAbilityRecords_.emplace(uiExtensionAbilityId, record); +} + +void UIExtensionAbilityConnectManager::RemoveUIExtensionAbilityRecord(const int32_t uiExtensionAbilityId) +{ + HILOG_DEBUG("UIExtensionAbilityId %{public}d.", uiExtensionAbilityId); + std::lock_guard lock(mutex_); + uiExtensionAbilityRecords_.erase(uiExtensionAbilityId); +} + +bool UIExtensionAbilityConnectManager::CheckUIExtensionAbilityLoaded(const int32_t uiExtensionAbilityId, + const std::string hostBundleName) +{ + HILOG_DEBUG("UIExtensionAbilityId %{public}d.", uiExtensionAbilityId); + std::lock_guard lock(mutex_); + // find target record firstly + auto it = uiExtensionAbilityRecords_.find(uiExtensionAbilityId); + if (it != uiExtensionAbilityRecords_.end() && it->second != nullptr) { + // check bundlename + HILOG_DEBUG("Stored host bundleName: %{public}s, input bundleName is %{public}s.", + it->second->hostBundleName_.c_str(), hostBundleName.c_str()); + if (it->second->hostBundleName_ == hostBundleName) { + return true; + } + } + HILOG_DEBUG("Not found stored id %{public}d.", uiExtensionAbilityId); + return false; +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/services/common/include/permission_constants.h b/services/common/include/permission_constants.h index de5f147539b..eb39fa03546 100644 --- a/services/common/include/permission_constants.h +++ b/services/common/include/permission_constants.h @@ -39,6 +39,7 @@ constexpr const char* PERMISSION_PROXY_AUTHORIZATION_URI = "ohos.permission.PROX constexpr const char* PERMISSION_EXEMPT_AS_CALLER = "ohos.permission.EXEMPT_AS_CALLER"; constexpr const char* PERMISSION_EXEMPT_AS_TARGET = "ohos.permission.EXEMPT_AS_TARGET"; constexpr const char* PERMISSION_PREPARE_TERMINATE = "ohos.permission.PREPARE_APP_TERMINATE"; +constexpr const char* PERMISSION_CONNECT_UI_EXTENSION_ABILITY = "ohos.permission.CONNECT_UI_EXTENSION_ABILITY"; } // namespace PermissionConstants } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index e5510aa2e87..f75398432f7 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -443,6 +443,7 @@ group("unittest") { "task_data_persistence_mgr_test:unittest", "task_handler_wrap_test:unittest", "trigger_Info_test:unittest", + "ui_extension_ability_test:unittest", "ui_extension_context_test:unittest", "ui_extension_utils_test:unittest", "uri_permission_impl_test:unittest", diff --git a/test/unittest/ui_extension_ability_test/BUILD.gn b/test/unittest/ui_extension_ability_test/BUILD.gn new file mode 100644 index 00000000000..256c8d8e628 --- /dev/null +++ b/test/unittest/ui_extension_ability_test/BUILD.gn @@ -0,0 +1,18 @@ +# 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("unittest") { + testonly = true + + deps = [ "ui_extension_connect_test:unittest" ] +} diff --git a/test/unittest/ui_extension_ability_test/ui_extension_connect_test/BUILD.gn b/test/unittest/ui_extension_ability_test/ui_extension_connect_test/BUILD.gn new file mode 100644 index 00000000000..6ae902bc224 --- /dev/null +++ b/test/unittest/ui_extension_ability_test/ui_extension_connect_test/BUILD.gn @@ -0,0 +1,53 @@ +# 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_unittest("ui_extension_connect_test") { + module_out_path = "ability_runtime/ui_extension" + + sources = [ "ui_extension_connect_test.cpp" ] + + configs = [ "${ability_runtime_services_path}/common:common_config" ] + + cflags = [] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + deps = [ + "//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", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_single", + ] +} + +group("unittest") { + testonly = true + deps = [ ":ui_extension_connect_test" ] +} diff --git a/test/unittest/ui_extension_ability_test/ui_extension_connect_test/ui_extension_connect_test.cpp b/test/unittest/ui_extension_ability_test/ui_extension_connect_test/ui_extension_connect_test.cpp new file mode 100644 index 00000000000..e0580d7da7b --- /dev/null +++ b/test/unittest/ui_extension_ability_test/ui_extension_connect_test/ui_extension_connect_test.cpp @@ -0,0 +1,101 @@ +/* + * 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 "ability_connect_callback_stub.h" +#include "ability_manager_client.h" +#include "hilog_wrapper.h" +#include "session_info.h" +#include "want.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace AAFwk { +class UIExtensionConnectTestConnection : public AbilityConnectionStub { +public: + UIExtensionConnectTestConnection() = default; + virtual ~UIExtensionConnectTestConnection() = default; + +private: + void OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int resultCode) override; + void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override; +}; + +void UIExtensionConnectTestConnection::OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int resultCode) +{ + HILOG_INFO("element: %{public}s", element.GetURI().c_str()); +} + +void UIExtensionConnectTestConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, + int resultCode) +{ + HILOG_INFO("element: %{public}s", element.GetURI().c_str()); +} + +class UIExtensionConnectTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +void UIExtensionConnectTest::SetUpTestCase(void) +{} + +void UIExtensionConnectTest::TearDownTestCase(void) +{} + +void UIExtensionConnectTest::SetUp() +{} + +void UIExtensionConnectTest::TearDown() +{} + +/** + * @tc.name: PermissionCheck_0100 + * @tc.desc: permission check test. + * @tc.type: FUNC + * @tc.require: issueI5OD2E + */ +HWTEST_F(UIExtensionConnectTest, PermissionCheck_0100, TestSize.Level1) +{ + HILOG_INFO("start."); + Want providerWant; + AppExecFwk::ElementName providerElement("0", "com.ohos.uiextensionprovider", "UIExtensionProvider", "entry"); + providerWant.SetElement(providerElement); + + auto connection = sptr::MakeSptr(); + ASSERT_NE(connection, nullptr); + + auto sessionInfo = sptr::MakeSptr(); + ASSERT_NE(sessionInfo, nullptr); + + auto connectInfo = sptr::MakeSptr(); + ASSERT_NE(connectInfo, nullptr); + + auto ret = AbilityManagerClient::GetInstance()->ConnectUIExtensionAbility(providerWant, connection, sessionInfo, + DEFAULT_INVAL_VALUE, connectInfo); + EXPECT_NE(ret, ERR_OK); + + HILOG_INFO("finish."); +} +} // namespace AAFwk +} // namespace OHOS -- Gitee