diff --git a/frameworks/c/ability_runtime/BUILD.gn b/frameworks/c/ability_runtime/BUILD.gn index ed64c6f091c5096d96380815094799d9dbdf182c..847c485424578467c035637e7d93ac65e049490c 100644 --- a/frameworks/c/ability_runtime/BUILD.gn +++ b/frameworks/c/ability_runtime/BUILD.gn @@ -49,6 +49,7 @@ ohos_shared_library("ability_runtime") { sources = [ "src/ability_business_error_utils.cpp", "src/application_context.cpp", + "src/load_ability_callback_impl.cpp", "src/start_options.cpp", "src/start_options_impl.cpp", "src/want_utils.cpp", @@ -59,6 +60,7 @@ ohos_shared_library("ability_runtime") { "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", "${ability_runtime_innerkits_path}/ability_manager:process_options", "${ability_runtime_innerkits_path}/ability_manager:start_window_option", + "${ability_runtime_innerkits_path}/app_manager:app_manager", "${ability_runtime_native_path}/appkit:app_context", ] @@ -66,11 +68,13 @@ ohos_shared_library("ability_runtime") { "ability_base:ability_base_want", "ability_base:want", "c_utils:utils", + "ffrt:libffrt", "hilog:libhilog", "image_framework:image_native", "image_framework:pixelmap", "ipc:ipc_core", "napi:ace_napi", + "samgr:samgr_proxy", ] if (ability_runtime_graphics) { diff --git a/frameworks/c/ability_runtime/include/ability_business_error_utils.h b/frameworks/c/ability_runtime/include/ability_business_error_utils.h index 83d34646962436fd4b678dd898b72240bacc2fde..4cc296078f3e8d882cac16eae9f441021c68fe45 100644 --- a/frameworks/c/ability_runtime/include/ability_business_error_utils.h +++ b/frameworks/c/ability_runtime/include/ability_business_error_utils.h @@ -22,6 +22,8 @@ AbilityRuntime_ErrorCode ConvertToCommonBusinessErrorCode(int32_t abilityManagerErrorCode); -AbilityRuntime_ErrorCode ConvertToAPI18BusinessErrorCode(int32_t abilityManagerErrorCode); +AbilityRuntime_ErrorCode ConvertToAPI17BusinessErrorCode(int32_t abilityManagerErrorCode); + +AbilityRuntime_ErrorCode ConvertToAPI21BusinessErrorCode(int32_t abilityManagerErrorCode); #endif // ABILITY_RUNTIME_ABILITY_BUSINESS_ERROR_UTILS_H diff --git a/frameworks/c/ability_runtime/include/load_ability_callback_impl.h b/frameworks/c/ability_runtime/include/load_ability_callback_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..01d26707cb1f16f8c105c0fdc12d8987ac4b7693 --- /dev/null +++ b/frameworks/c/ability_runtime/include/load_ability_callback_impl.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 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 ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_IMPL_H +#define ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_IMPL_H + +#include + +#include "ffrt.h" +#include "load_ability_callback_stub.h" + +namespace OHOS { +namespace AbilityRuntime { +using OHOS::AppExecFwk::LoadAbilityCallbackStub; +using OnFinishTask = std::function; +class LoadAbilityCallbackImpl : public LoadAbilityCallbackStub { +public: + explicit LoadAbilityCallbackImpl(OnFinishTask &&task) : task_(task) {} + virtual ~LoadAbilityCallbackImpl() = default; + + /** + * Callback to return pid. + * + * @param pid Process id. + */ + virtual void OnFinish(int32_t pid) override; + + void Cancel(); + +private: + ffrt::mutex taskMutex_; + OnFinishTask task_; +}; +} +} +#endif // ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_IMPL_H \ No newline at end of file diff --git a/frameworks/c/ability_runtime/src/ability_business_error_utils.cpp b/frameworks/c/ability_runtime/src/ability_business_error_utils.cpp index 05099eaa108502f94ab967cb29ad3c3b96876a30..43e4219c6cd9d43d8115bc875bf2881cab63085f 100644 --- a/frameworks/c/ability_runtime/src/ability_business_error_utils.cpp +++ b/frameworks/c/ability_runtime/src/ability_business_error_utils.cpp @@ -42,13 +42,17 @@ std::unordered_map g_innerToBusinessErrorComm { OHOS::AAFwk::ERR_APP_INSTANCE_KEY_NOT_SUPPORT, ABILITY_RUNTIME_ERROR_CODE_APP_INSTANCE_KEY_NOT_SUPPORTED }, { OHOS::AAFwk::ERR_NOT_SELF_APPLICATION, ABILITY_RUNTIME_ERROR_CODE_CROSS_APP }, }; - -std::unordered_map g_innerToBusinessErrorApi18Map { + +std::unordered_map g_innerToBusinessErrorApi17Map { { OHOS::AAFwk::ERR_MULTI_APP_NOT_SUPPORTED, ABILITY_RUNTIME_ERROR_CODE_MULTI_APP_NOT_SUPPORTED }, { OHOS::AAFwk::ERR_INVALID_APP_INSTANCE_KEY, ABILITY_RUNTIME_ERROR_CODE_INVALID_APP_INSTANCE_KEY }, { OHOS::AAFwk::ERR_MULTI_INSTANCE_NOT_SUPPORTED, ABILITY_RUNTIME_ERROR_MULTI_INSTANCE_NOT_SUPPORTED }, }; +std::unordered_map g_innerToBusinessErrorApi21Map { +{ OHOS::AAFwk::ERR_ATTACH_ABILITY_THREAD_FAILED, ABILITY_RUNTIME_ERROR_CODE_START_TIMEOUT }, +}; + AbilityRuntime_ErrorCode ConvertToCommonBusinessErrorCode(int32_t abilityManagerErrorCode) { TAG_LOGI(AAFwkTag::APPKIT, "ability errCode:%{public}d", abilityManagerErrorCode); @@ -60,7 +64,7 @@ AbilityRuntime_ErrorCode ConvertToCommonBusinessErrorCode(int32_t abilityManager return ABILITY_RUNTIME_ERROR_CODE_INTERNAL; } -AbilityRuntime_ErrorCode ConvertToAPI18BusinessErrorCode(int32_t abilityManagerErrorCode) +AbilityRuntime_ErrorCode ConvertToAPI17BusinessErrorCode(int32_t abilityManagerErrorCode) { TAG_LOGI(AAFwkTag::APPKIT, "ability errCode:%{public}d", abilityManagerErrorCode); auto errCode = ConvertToCommonBusinessErrorCode(abilityManagerErrorCode); @@ -68,8 +72,24 @@ AbilityRuntime_ErrorCode ConvertToAPI18BusinessErrorCode(int32_t abilityManagerE return errCode; } - auto it = g_innerToBusinessErrorApi18Map.find(abilityManagerErrorCode); - if (it != g_innerToBusinessErrorApi18Map.end()) { + auto it = g_innerToBusinessErrorApi17Map.find(abilityManagerErrorCode); + if (it != g_innerToBusinessErrorApi17Map.end()) { + return it->second; + } + + return ABILITY_RUNTIME_ERROR_CODE_INTERNAL; +} + +AbilityRuntime_ErrorCode ConvertToAPI21BusinessErrorCode(int32_t abilityManagerErrorCode) +{ + TAG_LOGI(AAFwkTag::APPKIT, "ability errCode:%{public}d", abilityManagerErrorCode); + auto errCode = ConvertToAPI17BusinessErrorCode(abilityManagerErrorCode); + if (errCode != ABILITY_RUNTIME_ERROR_CODE_INTERNAL) { + return errCode; + } + + auto it = g_innerToBusinessErrorApi21Map.find(abilityManagerErrorCode); + if (it != g_innerToBusinessErrorApi21Map.end()) { return it->second; } diff --git a/frameworks/c/ability_runtime/src/application_context.cpp b/frameworks/c/ability_runtime/src/application_context.cpp index 8224e0a0039c8bbce6757e38ce39b6161b5b97fd..e7ab30d5ae4307628d906419a29df586f555cf76 100644 --- a/frameworks/c/ability_runtime/src/application_context.cpp +++ b/frameworks/c/ability_runtime/src/application_context.cpp @@ -13,14 +13,25 @@ * limitations under the License. */ +#include +#include +#include +#include +#include "cpp/condition_variable.h" + #include "application_context.h" #include "ability_business_error_utils.h" #include "ability_manager_client.h" +#include "app_mgr_interface.h" #include "context.h" #include "context/application_context.h" +#include "ffrt.h" #include "hilog_tag_wrapper.h" +#include "load_ability_callback_impl.h" #include "start_options_impl.h" +#include "sys_mgr_client.h" +#include "system_ability_definition.h" #include "want_manager.h" #include "want_utils.h" @@ -29,6 +40,9 @@ using namespace OHOS::AAFwk; using namespace OHOS; namespace { +constexpr int32_t ATTACH_ABILITY_THREAD_TIMEOUT_TIME = 100 * 1000; // attach ability thread timeout, 100s +sptr g_appMgr = nullptr; + AbilityRuntime_ErrorCode WriteStringToBuffer( const std::string &src, char* buffer, const int32_t bufferSize, int32_t* writeLength) { @@ -55,6 +69,40 @@ AbilityRuntime_ErrorCode CheckParameters(char* buffer, int32_t* writeLength) } return ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; } + +sptr GetAppMgr() +{ + if (g_appMgr) { + return g_appMgr; + } + + auto sysMgrClient = DelayedSingleton::GetInstance(); + if (sysMgrClient == nullptr) { + return nullptr; + } + auto object = sysMgrClient->GetSystemAbility(APP_MGR_SERVICE_ID); + if (object == nullptr) { + return nullptr; + } + g_appMgr = OHOS::iface_cast(object); + return g_appMgr; +} + +AbilityRuntime_ErrorCode CheckAppMainThread() +{ + auto appMgrClient = GetAppMgr(); + if (appMgrClient == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null appMgr"); + return ABILITY_RUNTIME_ERROR_CODE_INTERNAL; + } + AppExecFwk::ChildProcessInfo childProcessInfo; + auto ret = appMgrClient->GetChildProcessInfoForSelf(childProcessInfo); + if (ret != ERR_OK && getpid() == gettid()) { + TAG_LOGE(AAFwkTag::APPKIT, "calling in app's main thread is not supported"); + return ABILITY_RUNTIME_ERROR_CODE_MAIN_THREAD_NOT_SUPPORTED; + } + return ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; +} } AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetCacheDir( @@ -376,7 +424,7 @@ AbilityRuntime_ErrorCode OH_AbilityRuntime_StartSelfUIAbilityWithStartOptions(Ab return ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID; } OHOS::AAFwk::StartOptions startOptions = options->GetInnerStartOptions(); - return ConvertToAPI18BusinessErrorCode(AbilityManagerClient::GetInstance()->StartSelfUIAbilityWithStartOptions( + return ConvertToAPI17BusinessErrorCode(AbilityManagerClient::GetInstance()->StartSelfUIAbilityWithStartOptions( abilityWant, startOptions)); } @@ -399,4 +447,56 @@ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetVersionCode(int6 } *versionCode = static_cast(appApplicationInfo->versionCode); return ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; +} + +AbilityRuntime_ErrorCode OH_AbilityRuntime_StartSelfUIAbilityWithPidResult(AbilityBase_Want *want, + AbilityRuntime_StartOptions *options, int32_t &targetPid) +{ + TAG_LOGD(AAFwkTag::APPKIT, "StartSelfUIAbilityWithPidResult called"); + auto ret = CheckAppMainThread(); + if (ret != ABILITY_RUNTIME_ERROR_CODE_NO_ERROR) { + TAG_LOGE(AAFwkTag::APPKIT, "CheckAppMainThread failed, ret=%{public}d", ret); + return ret; + } + ret = CheckWant(want); + if (ret != ABILITY_RUNTIME_ERROR_CODE_NO_ERROR) { + TAG_LOGE(AAFwkTag::APPKIT, "CheckWant failed: %{public}d", ret); + return ret; + } + if (options == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null options"); + return ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID; + } + Want abilityWant; + AbilityBase_ErrorCode errCode = CWantManager::TransformToWant(*want, false, abilityWant); + if (errCode != ABILITY_BASE_ERROR_CODE_NO_ERROR) { + TAG_LOGE(AAFwkTag::APPKIT, "transform error:%{public}d", errCode); + return ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID; + } + StartOptions startOptions = options->GetInnerStartOptions(); + ffrt::condition_variable callbackDoneCv; + std::atomic_bool done = false; + auto task = [&targetPid, &callbackDoneCv, &done](int32_t pidResult) { + targetPid = pidResult; + done.store(true); + callbackDoneCv.notify_all(); + }; + sptr callback = sptr::MakeSptr(std::move(task)); + auto result = AbilityManagerClient::GetInstance()->StartSelfUIAbilityWithPidResult( + abilityWant, startOptions, callback); + if (result != ERR_OK) { + callback->Cancel(); + return ConvertToAPI21BusinessErrorCode(result); + } + auto condition = [&done] { + return done.load(); + }; + ffrt::mutex callbackDoneMutex; + std::unique_lock lock(callbackDoneMutex); + if (!callbackDoneCv.wait_for(lock, std::chrono::milliseconds(ATTACH_ABILITY_THREAD_TIMEOUT_TIME), condition) || + targetPid < 0) { + callback->Cancel(); + return ABILITY_RUNTIME_ERROR_CODE_START_TIMEOUT; + } + return ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; } \ No newline at end of file diff --git a/frameworks/c/ability_runtime/src/load_ability_callback_impl.cpp b/frameworks/c/ability_runtime/src/load_ability_callback_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90ccf3a9438ee1ea67ccebf822c7e315ededb051 --- /dev/null +++ b/frameworks/c/ability_runtime/src/load_ability_callback_impl.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 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 "load_ability_callback_impl.h" + +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +void LoadAbilityCallbackImpl::OnFinish(int32_t pid) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "call OnFinish"); + std::unique_lock lock(taskMutex_); + if (task_) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "pid:%{public}d", pid); + task_(pid); + } +} + +void LoadAbilityCallbackImpl::Cancel() +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "call Cancel"); + std::unique_lock lock(taskMutex_); + task_ = nullptr; +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file 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 cf1e41c67a1f28a3933c0c3c1dff49c60f4da6bd..b77015da00ba829a59703ec066c317063357073a 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -30,8 +30,12 @@ #include "want.h" #include "intent_exemption_info.h" #include "ihidden_start_observer.h" +#include "iload_ability_callback.h" namespace OHOS { +namespace AppExecFwk { +class ILoadAbilityCallback; +} namespace AAFwk { class Snapshot; class ISnapshotHandler; @@ -63,6 +67,17 @@ public: */ ErrCode StartSelfUIAbilityWithStartOptions(const Want &want, const StartOptions &options); + /** + * Starts self UIAbility with start options and receives the process ID. Supported only on 2-in-1 devices. + * + * @param want, the want of the ability to start. + * @param options, the startOptions of the ability to start. + * @param callback, the callback to get target process id. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback); + /** * AttachAbilityThread, ability call this interface after loaded. * diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h index b39bdebdf56b62f7365b0ba9a5f004e26442b6d7..137755e14bd198e030041e32e945bea31addfbd6 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -1317,6 +1317,11 @@ enum NativeFreeInstallError { */ ERR_WRITE_INT_FAILED = 29360221, + /* + * Result(29360222) for attaching ability failed. + */ + ERR_ATTACH_ABILITY_THREAD_FAILED = 29360222, + /** * Undefine error code. */ 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 81adffada17a43eccf94862586c125f46d26e2ce..300da7ba8cbd716f0ba27e6a6d1221ab0c9b0816 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -38,6 +38,7 @@ #include "iability_controller.h" #include "iability_manager_collaborator.h" #include "iacquire_share_data_callback_interface.h" +#include "iload_ability_callback.h" #include "insight_intent/insight_intent_execute_param.h" #include "insight_intent/insight_intent_execute_result.h" #include "insight_intent/insight_intent_info_for_query.h" @@ -131,6 +132,20 @@ public: return 0; } + /** + * Starts self UIAbility with start options and receives the process ID. Supported only on 2-in-1 devices. + * + * @param want, the want of the ability to start. + * @param options, the startOptions of the ability to start. + * @param callback, the callback to get target process id. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) + { + return 0; + } + /** * StartAbility with want, send want to ability manager service. * diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h index a0994651638608c902fad13443ad6e8ce5f8655c..aa2407a3eebb6fb093b42358e08ad6d4ab98ed10 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h @@ -674,6 +674,9 @@ enum class AbilityManagerInterfaceCode { // preload application PRELOAD_APPLICATION = 6151, + + // start self uiability with startOptions and receives the pid + START_SELF_UI_ABILITY_WITH_PID_RESULT = 6152, }; } // namespace AAFwk } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/process_options.h b/interfaces/inner_api/ability_manager/include/process_options.h index 5a4a540bf2bbc4d5716bf8f4cc29e1d982bd29fa..d6924e8241d510b4ebf87b5fd7e08f5eff0726f3 100644 --- a/interfaces/inner_api/ability_manager/include/process_options.h +++ b/interfaces/inner_api/ability_manager/include/process_options.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 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 @@ -58,6 +58,7 @@ public: bool isRestartKeepAlive = false; bool isStartFromNDK = false; bool isPreloadStart = false; + bool shouldReturnPid = false; ProcessMode processMode = ProcessMode::UNSPECIFIED; StartupVisibility startupVisibility = StartupVisibility::UNSPECIFIED; std::string processName; diff --git a/interfaces/inner_api/ability_manager/include/start_options.h b/interfaces/inner_api/ability_manager/include/start_options.h index f9ba90cd6e845076be59c666e24de421d31df290..cf5f0c4d23bcb2a74ff3e9a72cc641aa3516013d 100644 --- a/interfaces/inner_api/ability_manager/include/start_options.h +++ b/interfaces/inner_api/ability_manager/include/start_options.h @@ -20,6 +20,7 @@ #include "ability_info.h" #include "ability_window_configuration.h" +#include "iremote_object.h" #include "parcel.h" namespace OHOS { @@ -80,6 +81,7 @@ public: std::vector supportWindowModes_; std::string requestId_; std::shared_ptr windowCreateParams_ = nullptr; + sptr loadAbilityCallback_ = nullptr; StartOptions() = default; ~StartOptions() = default; diff --git a/interfaces/inner_api/app_manager/BUILD.gn b/interfaces/inner_api/app_manager/BUILD.gn index d83479d9bdfde680cff04a0cdafedcf0ddfe955e..8066ce4967bcfcb2da1c271a6bf332ad8baa5d44 100644 --- a/interfaces/inner_api/app_manager/BUILD.gn +++ b/interfaces/inner_api/app_manager/BUILD.gn @@ -101,6 +101,8 @@ ohos_shared_library("app_manager") { "src/appmgr/fault_data.cpp", "src/appmgr/kia_interceptor_proxy.cpp", "src/appmgr/kia_interceptor_stub.cpp", + "src/appmgr/load_ability_callback_proxy.cpp", + "src/appmgr/load_ability_callback_stub.cpp", "src/appmgr/memory_level_info.cpp", "src/appmgr/native_child_notify_proxy.cpp", "src/appmgr/native_child_notify_stub.cpp", diff --git a/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_interface.h b/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_interface.h index c90a12c037e8755f78b7cf182b2ccadb87260dcd..bde4ece9b723245c9335a8ac6823c5f232a7127f 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_interface.h +++ b/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_interface.h @@ -23,6 +23,7 @@ #include "application_info.h" #include "configuration.h" #include "iapp_state_callback.h" +#include "iload_ability_callback.h" #include "iremote_broker.h" #include "iremote_object.h" #include "istart_specified_ability_response.h" @@ -45,11 +46,13 @@ public: * @param preToken, the unique identification to call the ability. * @param abilityInfo, the ability information. * @param appInfo, the app information. + * @param callback, the callback to get process id. * @return */ virtual void LoadAbility(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const std::shared_ptr &want, std::shared_ptr loadParam) {}; + const std::shared_ptr &want, std::shared_ptr loadParam, + sptr callback = nullptr) {}; /** * TerminateAbility, call TerminateAbility() through the proxy object, terminate the token ability. diff --git a/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_proxy.h b/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_proxy.h index 56d971ac3def9f121dcefbc5c22e1e36712bab8f..53fb4abff965122fa5265386ac9aa42e15242039 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_proxy.h +++ b/interfaces/inner_api/app_manager/include/appmgr/ams_mgr_proxy.h @@ -34,11 +34,13 @@ public: * @param preToken, the unique identification to call the ability. * @param abilityInfo, the ability information. * @param appInfo, the app information. + * @param callback, the callback to get process id. * @return */ virtual void LoadAbility(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const std::shared_ptr &want, std::shared_ptr loadParam) override; + const std::shared_ptr &want, std::shared_ptr loadParam, + sptr callback = nullptr) override; /** * TerminateAbility, call TerminateAbility() through the proxy object, terminate the token ability. diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h index f0d825d8021e80723b35fc4ea6b491b2a4eccd36..f846e868a5039e78c1d3bb9a9c9de67eff75bb5f 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h @@ -62,10 +62,12 @@ public: * @param appInfo Application information. * @param want Want. * @param loadParam load ability param. + * @param callback, the callback to get process id. * @return Returns RESULT_OK on success, others on failure. */ virtual AppMgrResultCode LoadAbility(const AbilityInfo &abilityInfo, const ApplicationInfo &appInfo, - const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam); + const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam, + sptr callback = nullptr); /** * Terminate ability. diff --git a/interfaces/inner_api/app_manager/include/appmgr/iload_ability_callback.h b/interfaces/inner_api/app_manager/include/appmgr/iload_ability_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..034b5c5199f038b88cd8080edf2b45e8d8a523c8 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/iload_ability_callback.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 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_ILOAD_ABILITY_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_ILOAD_ABILITY_CALLBACK_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace AppExecFwk { +class ILoadAbilityCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.appexecfwk.ILoadAbilityCallback"); + + /** + * Callback to return pid. + * + * @param pid Process id. + */ + virtual void OnFinish(int32_t pid) = 0; + + enum class Message { + TRANSACT_ON_FINISH = 0, + }; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ILOAD_ABILITY_CALLBACK_H diff --git a/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_proxy.h b/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..4783317b22ea7a9ac8902ca8d74dd3b1807ae127 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_proxy.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 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_LOAD_ABILITY_CALLBACK_PROXY_H +#define OHOS_ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_PROXY_H + +#include "iremote_proxy.h" + +#include "iload_ability_callback.h" + +namespace OHOS { +namespace AppExecFwk { +class LoadAbilityCallbackProxy : public IRemoteProxy { +public: + explicit LoadAbilityCallbackProxy(const sptr &impl); + virtual ~LoadAbilityCallbackProxy() = default; + + /** + * Callback to return pid. + * + * @param pid Process id. + */ + virtual void OnFinish(int32_t pid) override; + +private: + bool WriteInterfaceToken(MessageParcel &data); + static inline BrokerDelegator delegator_; + int32_t SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_PROXY_H diff --git a/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_stub.h b/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..15c0dab05e48ce23cb9c309febeca890321da4e6 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/load_ability_callback_stub.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 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_LOAD_ABILITY_CALLBACK_STUB_H +#define OHOS_ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_STUB_H + +#include +#include + +#include "iload_ability_callback.h" +#include "iremote_stub.h" +#include "nocopyable.h" +#include "string_ex.h" + +namespace OHOS { +namespace AppExecFwk { +class LoadAbilityCallbackStub : public IRemoteStub { +public: + LoadAbilityCallbackStub() = default; + virtual ~LoadAbilityCallbackStub() = default; + + virtual int OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t HandleOnFinish(MessageParcel &data, MessageParcel &reply); + + DISALLOW_COPY_AND_MOVE(LoadAbilityCallbackStub); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_LOAD_ABILITY_CALLBACK_STUB_H diff --git a/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_proxy.cpp b/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_proxy.cpp index 2da9a32ce365d37aa62f3f4f68fe6de9d9861898..927d8950842df0e0240f4830ebfa12f7e305e67e 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_proxy.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_proxy.cpp @@ -68,7 +68,8 @@ bool AmsMgrProxy::WriteInterfaceToken(MessageParcel &data) void AmsMgrProxy::LoadAbility(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const std::shared_ptr &want, std::shared_ptr loadParam) + const std::shared_ptr &want, std::shared_ptr loadParam, + sptr callback) { TAG_LOGD(AAFwkTag::APPMGR, "start"); if (!abilityInfo || !appInfo) { @@ -98,6 +99,17 @@ void AmsMgrProxy::LoadAbility(const std::shared_ptr &abilityInfo, TAG_LOGE(AAFwkTag::APPMGR, "Write data loadParam failed"); return; } + if (callback != nullptr && callback->AsObject() != nullptr) { + if (!data.WriteBool(true) || !data.WriteRemoteObject(callback->AsObject())) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to write flag and callback"); + return; + } + } else { + if (!data.WriteBool(false)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to write flag"); + return; + } + } int32_t ret = SendTransactCmd(static_cast(IAmsMgr::Message::LOAD_ABILITY), data, reply, option); if (ret != NO_ERROR) { diff --git a/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_stub.cpp b/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_stub.cpp index 2bb33682b06d3545703db0fc87d36fa1dd95cb9d..2f19a48db721d9e950d24fa1b5d1a092132fb532 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_stub.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/ams_mgr_stub.cpp @@ -264,8 +264,13 @@ ErrCode AmsMgrStub::HandleLoadAbility(MessageParcel &data, MessageParcel &reply) TAG_LOGE(AAFwkTag::APPMGR, "ReadParcelable loadParam failed"); return ERR_APPEXECFWK_PARCEL_ERROR; } + sptr callback = nullptr; + if (data.ReadBool()) { + sptr obj = data.ReadRemoteObject(); + callback = iface_cast(obj); + } - LoadAbility(abilityInfo, appInfo, want, loadParam); + LoadAbility(abilityInfo, appInfo, want, loadParam, callback); return NO_ERROR; } diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp index 92c19f685cf5fbd92e1d35c1bd961687e9f74e7d..7833693174d2fd7f70d9f8cd8f15b30739281228 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp @@ -160,7 +160,7 @@ AppMgrClient::~AppMgrClient() {} AppMgrResultCode AppMgrClient::LoadAbility(const AbilityInfo &abilityInfo, const ApplicationInfo &appInfo, - const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam) + const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam, sptr callback) { sptr service = iface_cast(mgrHolder_->GetRemoteObject()); if (service != nullptr) { @@ -171,7 +171,7 @@ AppMgrResultCode AppMgrClient::LoadAbility(const AbilityInfo &abilityInfo, const std::shared_ptr appInfoPtr = std::make_shared(appInfo); std::shared_ptr wantPtr = std::make_shared(want); auto loadParamPtr = std::make_shared(loadParam); - amsService->LoadAbility(abilityInfoPtr, appInfoPtr, wantPtr, loadParamPtr); + amsService->LoadAbility(abilityInfoPtr, appInfoPtr, wantPtr, loadParamPtr, callback); return AppMgrResultCode::RESULT_OK; } } diff --git a/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_proxy.cpp b/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4779e417f7c133d1df2aaa52b35118874b9c1c5f --- /dev/null +++ b/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_proxy.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 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 "load_ability_callback_proxy.h" + +#include "hilog_tag_wrapper.h" +#include "ipc_types.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +const int32_t ERR_INVALID_STUB = 32; +} +LoadAbilityCallbackProxy::LoadAbilityCallbackProxy( + const sptr &impl) : IRemoteProxy(impl) +{} + +bool LoadAbilityCallbackProxy::WriteInterfaceToken(MessageParcel &data) +{ + if (!data.WriteInterfaceToken(LoadAbilityCallbackProxy::GetDescriptor())) { + TAG_LOGE(AAFwkTag::APPMGR, "write interface token failed"); + return false; + } + return true; +} + +int32_t LoadAbilityCallbackProxy::SendTransactCmd(uint32_t code, MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + sptr remote = Remote(); + if (remote == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "Remote is nullptr."); + return ERR_NULL_OBJECT; + } + + return remote->SendRequest(code, data, reply, option); +} + +void LoadAbilityCallbackProxy::OnFinish(int32_t pid) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!WriteInterfaceToken(data)) { + return; + } + if (!data.WriteInt32(pid)) { + TAG_LOGE(AAFwkTag::APPMGR, "write pid failed"); + return; + } + int32_t ret = SendTransactCmd( + static_cast(ILoadAbilityCallback::Message::TRANSACT_ON_FINISH), + data, reply, option); + if (ret != NO_ERROR && ret != ERR_INVALID_STUB) { + TAG_LOGE(AAFwkTag::APPMGR, "SendRequest is failed, error code: %{public}d.", ret); + } +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_stub.cpp b/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..702a8600f888f21a6faa232b5c54825a27de852c --- /dev/null +++ b/interfaces/inner_api/app_manager/src/appmgr/load_ability_callback_stub.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 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 "load_ability_callback_stub.h" + +#include "hilog_tag_wrapper.h" +#include "ipc_types.h" + +namespace OHOS { +namespace AppExecFwk { +int LoadAbilityCallbackStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + std::u16string descriptor = LoadAbilityCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + TAG_LOGE(AAFwkTag::APPMGR, "local descriptor is not equal to remote."); + return ERR_INVALID_STATE; + } + + if (static_cast(code) == Message::TRANSACT_ON_FINISH) { + return HandleOnFinish(data, reply); + } + TAG_LOGW(AAFwkTag::APPMGR, "LoadAbilityCallbackStub::OnRemoteRequest, default case, need check"); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t LoadAbilityCallbackStub::HandleOnFinish(MessageParcel &data, MessageParcel &reply) +{ + int32_t pid = data.ReadInt32(); + OnFinish(pid); + return NO_ERROR; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/interfaces/kits/c/ability_runtime/ability_runtime_common.h b/interfaces/kits/c/ability_runtime/ability_runtime_common.h index 7c2e98d4a632a7166b813dd3b6b93bd4e73de91b..a7ad2fdfc182257adf2577af3bbb62baec1a6629 100644 --- a/interfaces/kits/c/ability_runtime/ability_runtime_common.h +++ b/interfaces/kits/c/ability_runtime/ability_runtime_common.h @@ -143,6 +143,16 @@ typedef enum { * @since 21 */ ABILITY_RUNTIME_ERROR_CODE_GET_APPLICATION_INFO_FAILED = 16000081, + /** + * @error Starting UIAbility times out. + * @since 21 + */ + ABILITY_RUNTIME_ERROR_CODE_START_TIMEOUT = 16000133, + /** + * @error The API does not support being called in the main thread. + * @since 21 + */ + ABILITY_RUNTIME_ERROR_CODE_MAIN_THREAD_NOT_SUPPORTED = 16000134, } AbilityRuntime_ErrorCode; #ifdef __cplusplus diff --git a/interfaces/kits/c/ability_runtime/application_context.h b/interfaces/kits/c/ability_runtime/application_context.h index b89be845b3eae15ca461b53cf5e817bbfa85f095..99dad12ff1622d1aeb5d11e2b3194895e8dfc403 100644 --- a/interfaces/kits/c/ability_runtime/application_context.h +++ b/interfaces/kits/c/ability_runtime/application_context.h @@ -343,6 +343,46 @@ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLaunchParameter( */ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLatestParameter( char* buffer, const int32_t bufferSize, int32_t* writeLength); + +/** + * @brief Starts self UIAbility with start options and receives the process ID. + * + * @permission {@code ohos.permission.NDK_START_SELF_UI_ABILITY} + * @param want The arguments passed to start self UIAbility. + * For details, see {@link AbilityBase_Want}. + * @param options The start options passed to start self UIAbility. + * For details, see {@link AbilityRuntime_StartOptions}. + * @param pid The process ID of the started UIAbility. + * @return Returns {@link ABILITY_RUNTIME_ERROR_CODE_NO_ERROR} if the call is successful. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_PERMISSION_DENIED} if the caller has no correct permission. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID} if the arguments provided is invalid. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_NOT_SUPPORTED} if the device does not support starting self uiability. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_NO_SUCH_ABILITY} if the target ability does not exist. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_INCORRECT_ABILITY_TYPE} if the ability type is incorrect. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_CROWDTEST_EXPIRED} if the crowdtesting application expires. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_WUKONG_MODE} if the ability cannot be started in Wukong mode. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_CONTROLLED} if the app is controlled. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_EDM_CONTROLLED} if the app is controlled by EDM. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_CROSS_APP} if the caller tries to start a different application. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_INTERNAL} if internal error occurs. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_NOT_TOP_ABILITY} if the caller is not foreground process. + * Returns {@link ABILITY_RUNTIME_ERROR_VISIBILITY_SETTING_DISABLED} if setting visibility is disabled. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_MULTI_APP_NOT_SUPPORTED} + * if the app clone or multi-instance is not supported. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_INVALID_APP_INSTANCE_KEY} if the app instance key is invalid. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_UPPER_LIMIT_REACHED} if the number of app instances reached the limit. + * Returns {@link ABILITY_RUNTIME_ERROR_MULTI_INSTANCE_NOT_SUPPORTED} if the multi-instance is not supported. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_APP_INSTANCE_KEY_NOT_SUPPORTED} + * if the APP_INSTANCE_KEY cannot be specified. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_START_TIMEOUT} if starting UIAbility times out. + * Returns {@link ABILITY_RUNTIME_ERROR_CODE_MAIN_THREAD_NOT_SUPPORTED} + * if the API is called in the main thread of the app. + * For details, see {@link AbilityRuntime_ErrorCode}. + * @since 21 + */ +AbilityRuntime_ErrorCode OH_AbilityRuntime_StartSelfUIAbilityWithPidResult(AbilityBase_Want *want, + AbilityRuntime_StartOptions *options, int32_t &targetPid); + #ifdef __cplusplus } // extern "C" #endif diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index bd0f047dac8d3918c05b1f62489e7d2020875e72..08b6615645db03d9e211bc8b25749b3106e62a56 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -55,6 +55,17 @@ public: virtual int StartSelfUIAbilityWithStartOptions(const Want &want, const StartOptions &options) override; + /** + * Starts self UIAbility with start options and receives the process ID. Supported only on 2-in-1 devices. + * + * @param want, the want of the ability to start. + * @param options, the startOptions of the ability to start. + * @param callback, the callback to get target process id. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) override; + /** * StartAbility with want, send want to ability manager service. * diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 2bcc0314ac1d407ab69e376f276f48a8a46d4990..680a6eac8f5b6cebb92a9b18ab791e5f8a12d4ca 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -141,6 +141,17 @@ public: virtual int StartSelfUIAbilityWithStartOptions(const Want &want, const StartOptions &options) override; + /** + * Starts self UIAbility with start options and receives the process ID. Supported only on 2-in-1 devices. + * + * @param want, the want of the ability to start. + * @param options, the startOptions of the ability to start. + * @param callback, the callback to get target process id. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) override; + /** * StartAbility with want, send want to ability manager service. * diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index f454f000ba75dfe680252d6dd977dafc9a9742e0..15be18ac110dfff57c0bbb1c207e4f1849f05786 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -81,6 +81,7 @@ private: int MinimizeUIExtensionAbilityInner(MessageParcel &data, MessageParcel &reply); int MinimizeUIAbilityBySCBInner(MessageParcel &data, MessageParcel &reply); int AttachAbilityThreadInner(MessageParcel &data, MessageParcel &reply); + int NotifyAttachAbilityThreadDoneInner(MessageParcel &data, MessageParcel &reply); int AbilityTransitionDoneInner(MessageParcel &data, MessageParcel &reply); int AbilityWindowConfigTransitionDoneInner(MessageParcel &data, MessageParcel &reply); int ScheduleConnectAbilityDoneInner(MessageParcel &data, MessageParcel &reply); @@ -95,6 +96,7 @@ private: int32_t UpgradeAppInner(MessageParcel &data, MessageParcel &reply); int StartSelfUIAbilityInner(MessageParcel &data, MessageParcel &reply); int StartSelfUIAbilityWithStartOptionsInner(MessageParcel &data, MessageParcel &reply); + int StartSelfUIAbilityWithPidResultInner(MessageParcel &data, MessageParcel &reply); int StartAbilityInner(MessageParcel &data, MessageParcel &reply); int StartAbilityInnerSpecifyTokenId(MessageParcel &data, MessageParcel &reply); int StartAbilityByUIContentSessionAddCallerInner(MessageParcel &data, MessageParcel &reply); diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 19d12eb7486c29bbac055bc856e895e997032f39..cb936ddc609462e60c7ba00e7979ad3089aee57e 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -52,6 +52,9 @@ #endif namespace OHOS { +namespace AppExecFwk { +class ILoadAbilityCallback; +} namespace AAFwk { using Closure = std::function; @@ -411,7 +414,8 @@ public: * * @return Returns ERR_OK on success, others on failure. */ - int LoadAbility(bool isShellCall = false, bool isStartupHide = false); + int LoadAbility(bool isShellCall = false, bool isStartupHide = false, + sptr callback = nullptr); /** * foreground the ability. @@ -425,7 +429,8 @@ public: * */ void ProcessForegroundAbility( - uint32_t tokenId, uint32_t sceneFlag = 0, bool isShellCall = false, bool isStartupHide = false); + uint32_t tokenId, uint32_t sceneFlag = 0, bool isShellCall = false, bool isStartupHide = false, + sptr callback = nullptr); /** * post foreground timeout task for ui ability. @@ -1270,6 +1275,16 @@ public: return isPreloadStart_.load(); } + inline void SetShouldReturnPid(bool shouldReturnPid) + { + shouldReturnPid_.store(shouldReturnPid); + } + + inline bool ShouldReturnPid() const + { + return shouldReturnPid_.load(); + } + inline void SetPreloaded() { isPreloaded_.store(true); @@ -1395,6 +1410,7 @@ private: #endif void SendAppStartupTypeEvent(const AppExecFwk::AppStartType startType); std::atomic isPreloadStart_ = false; // is ability started via preload + std::atomic shouldReturnPid_ = false; static std::atomic abilityRecordId; bool isReady_ = false; // is ability thread attached? diff --git a/services/abilitymgr/include/app_scheduler.h b/services/abilitymgr/include/app_scheduler.h index bdff8680370a94ff31c6ed6bc8c9f26b8973d2d1..8ce434fd6749714b225022887159b66146162b73 100644 --- a/services/abilitymgr/include/app_scheduler.h +++ b/services/abilitymgr/include/app_scheduler.h @@ -159,10 +159,12 @@ public: * @param abilityInfo, ability info. * @param applicationInfo, application info. * @param want ability want + * @param callback, the callback to get process id. * @return true on success ,false on failure. */ int LoadAbility(const AbilityRuntime::LoadParam &loadParam, const AppExecFwk::AbilityInfo &abilityInfo, - const AppExecFwk::ApplicationInfo &applicationInfo, const Want &want); + const AppExecFwk::ApplicationInfo &applicationInfo, const Want &want, + sptr callback = nullptr); /** * terminate ability with token. diff --git a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h index 80ed39a04a73711d23e3b3f120cdea8173e09388..fdf6d52b83fc336182043f71864142965f717c6e 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -442,7 +442,7 @@ private: // byCall int CallAbilityLocked(const AbilityRequest &abilityRequest, std::string &errMsg); - sptr CreateSessionInfo(const AbilityRequest &abilityRequest, int32_t requestId) const; + sptr CreateSessionInfo(const AbilityRequest &abilityRequest, int32_t requestId); int NotifySCBPendingActivation(sptr &sessionInfo, const AbilityRequest &abilityRequest, std::string &errMsg); std::pair>, std::vector> @@ -529,6 +529,7 @@ private: void HandleAbilitiesNormalSessionInfo(AbilityRequest &abilityRequest, std::shared_ptr abilitiesRequest, int32_t requestId); void RemoveInstanceKey(const AbilityRequest &abilityRequest) const; + sptr GetLoadAbilityCallback(int32_t requestId); int32_t userId_ = -1; mutable ffrt::mutex sessionLock_; @@ -536,6 +537,7 @@ private: std::unordered_map> lowMemKillAbilityMap_; std::unordered_map> tmpAbilityMap_; std::unordered_map, std::list> callRequestCache_; + std::map> loadAbilityCallbackMap_; std::list> terminateAbilityList_; sptr rootSceneSession_; sptr handler_; diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index 8fc684015757d3ab9911fb862809eb937fe82055..7e1ade3b0c80b1c52366d589d0c045eef37429d2 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -20,6 +20,7 @@ #endif // WITH_DLP #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" +#include "iload_ability_callback.h" #include "iservice_registry.h" #ifdef SUPPORT_SCREEN #include "scene_board_judgement.h" @@ -2192,7 +2193,7 @@ ErrCode AbilityManagerClient::QueryAtomicServiceStartupRule(sptr ErrCode AbilityManagerClient::StartSelfUIAbility(const Want &want) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "call"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "call StartSelfUIAbilityWithStartOptions"); auto abms = GetAbilityManager(); CHECK_POINTER_RETURN_NOT_CONNECTED(abms); return abms->StartSelfUIAbility(want); @@ -2201,12 +2202,21 @@ ErrCode AbilityManagerClient::StartSelfUIAbility(const Want &want) ErrCode AbilityManagerClient::StartSelfUIAbilityWithStartOptions(const Want &want, const StartOptions &options) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "call"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "call StartSelfUIAbilityWithStartOptions"); auto abms = GetAbilityManager(); CHECK_POINTER_RETURN_NOT_CONNECTED(abms); return abms->StartSelfUIAbilityWithStartOptions(want, options); } +ErrCode AbilityManagerClient::StartSelfUIAbilityWithPidResult(const Want &want, + StartOptions &options, sptr callback) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "call StartSelfUIAbilityWithPidResult"); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + return abms->StartSelfUIAbilityWithPidResult(want, options, callback); +} + void AbilityManagerClient::PrepareTerminateAbilityDone(sptr token, bool isTerminate) { TAG_LOGI(AAFwkTag::ABILITYMGR, "call PrepareTerminateAbilityDone"); diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index 7742e098d46cd4ab421d700b720617cffb5a27ff..9129673edee68539ca762ca7523420c020e28bb3 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -6485,6 +6485,47 @@ int32_t AbilityManagerProxy::StartSelfUIAbilityWithStartOptions(const Want &want return reply.ReadInt32(); } +int32_t AbilityManagerProxy::StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (callback == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null callback"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + + if (!WriteInterfaceToken(data)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write token fail"); + return ERR_WRITE_INTERFACE_CODE; + } + + if (!data.WriteParcelable(&want)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write want fail"); + return ERR_WRITE_WANT; + } + + if (!data.WriteParcelable(&options)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write startOptions fail"); + return ERR_WRITE_START_OPTIONS; + } + + if (!data.WriteRemoteObject(callback->AsObject())) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write callback fail"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + + auto error = SendRequest(AbilityManagerInterfaceCode::START_SELF_UI_ABILITY_WITH_PID_RESULT, + data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "request error:%{public}d", error); + return error; + } + return reply.ReadInt32(); +} + void AbilityManagerProxy::PrepareTerminateAbilityDone(const sptr &token, bool isTerminate) { MessageParcel data; diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index a589233dd53fc41f6100173e7ae77a9bd2cb8525..a061bdfd3abe29c38075d073b7f4c015ccc8c28c 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -6503,7 +6503,7 @@ int AbilityManagerService::AttachAbilityThread( { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); XCOLLIE_TIMER_LESS(__PRETTY_FUNCTION__); - TAG_LOGI(AAFwkTag::ABILITYMGR, "called"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "AttachAbilityThread called"); CHECK_POINTER_AND_RETURN(scheduler, ERR_INVALID_VALUE); if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && !VerificationAllToken(token)) { return ERR_INVALID_VALUE; @@ -14770,6 +14770,26 @@ int AbilityManagerService::StartSelfUIAbilityWithStartOptions(const Want &want, return StartSelfUIAbilityInner(param); } +int AbilityManagerService::StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) +{ + XCOLLIE_TIMER_LESS(__PRETTY_FUNCTION__); + TAG_LOGI(AAFwkTag::ABILITYMGR, "StartSelfUIAbilityWithPidResult"); + CHECK_POINTER_AND_RETURN(callback, ERR_INVALID_VALUE); + + if (options.processOptions == nullptr) { + options.processOptions = std::make_shared(); + } + options.processOptions->shouldReturnPid = true; + options.loadAbilityCallback_ = callback->AsObject(); + auto ret = StartSelfUIAbilityWithStartOptions(want, options); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartSelfUIAbilityWithStartOptions failed:%{public}d", ret); + return ret; + } + return ERR_OK; +} + bool AbilityManagerService::CheckCrossUser(const int32_t userId, AppExecFwk::ExtensionAbilityType extensionType) { if (AAFwk::UIExtensionUtils::IsEnterpriseAdmin(extensionType) || JudgeMultiUserConcurrency(userId)) { diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index 09dd9bb11b318b3f607ea791f266426ae06fe0cd..54b5ebb3a75d7ec23020d72c755092fb085e0db8 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -909,6 +909,9 @@ int AbilityManagerStub::OnRemoteRequestInnerTwentyFirst(uint32_t code, MessagePa if (interfaceCode == AbilityManagerInterfaceCode::PRELOAD_APPLICATION) { return PreloadApplicationInner(data, reply); } + if (interfaceCode == AbilityManagerInterfaceCode::START_SELF_UI_ABILITY_WITH_PID_RESULT) { + return StartSelfUIAbilityWithPidResultInner(data, reply); + } return ERR_CODE_NOT_EXIST; } @@ -4614,6 +4617,28 @@ int32_t AbilityManagerStub::StartSelfUIAbilityWithStartOptionsInner(MessageParce return NO_ERROR; } +int32_t AbilityManagerStub::StartSelfUIAbilityWithPidResultInner(MessageParcel &data, MessageParcel &reply) +{ + sptr want = data.ReadParcelable(); + if (want == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "want null"); + return ERR_READ_WANT; + } + sptr options = data.ReadParcelable(); + if (options == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "startOptions null"); + return ERR_READ_START_OPTIONS; + } + auto callback = iface_cast(data.ReadRemoteObject()); + int32_t result = StartSelfUIAbilityWithPidResult(*want, *options, callback); + if (!reply.WriteInt32(result)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write StartSelfUIAbilityWithPidResult result fail"); + return ERR_WRITE_START_SELF_UI_ABILITY_RESULT; + } + want->CloseAllFd(); + return NO_ERROR; +} + int32_t AbilityManagerStub::PrepareTerminateAbilityDoneInner(MessageParcel &data, MessageParcel &reply) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call PrepareTerminateAbilityDoneInner"); diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 06feaf73301ef786365b83ae787b5f2b26e408f3..d70822bc4d39b85246a1382fb089647574739e6d 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -246,16 +246,17 @@ std::shared_ptr AbilityRecord::CreateAbilityRecord(const AbilityR abilityRecord->SetAppIndex(appIndex); abilityRecord->SetSecurityFlag(abilityRequest.want.GetBoolParam(DLP_PARAMS_SECURITY_FLAG, false)); abilityRecord->SetCallerAccessTokenId(abilityRequest.callerAccessTokenId); - if (abilityRequest.processOptions != nullptr && abilityRequest.processOptions->isPreloadStart) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "start by preload"); - abilityRecord->SetPreloadStart(true); + if (abilityRequest.processOptions != nullptr) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "isPreloadStart:%{public}d,shouldReturnPid:%{public}d", + abilityRequest.processOptions->isPreloadStart, abilityRequest.processOptions->shouldReturnPid); + abilityRecord->SetPreloadStart(abilityRequest.processOptions->isPreloadStart); + abilityRecord->SetShouldReturnPid(abilityRequest.processOptions->shouldReturnPid); } abilityRecord->sessionInfo_ = abilityRequest.sessionInfo; if (AppUtils::GetInstance().IsMultiProcessModel() && abilityRequest.abilityInfo.isStageBasedModel && - abilityRequest.abilityInfo.type == AppExecFwk::AbilityType::PAGE && - !abilityRequest.customProcess.empty()) { - abilityRecord->SetCustomProcessFlag(abilityRequest.customProcess); - } + abilityRequest.abilityInfo.type == AppExecFwk::AbilityType::PAGE && !abilityRequest.customProcess.empty()) { + abilityRecord->SetCustomProcessFlag(abilityRequest.customProcess); + } if (abilityRequest.sessionInfo != nullptr) { abilityRecord->instanceKey_ = abilityRequest.sessionInfo->instanceKey; } @@ -278,8 +279,7 @@ std::shared_ptr AbilityRecord::CreateAbilityRecord(const AbilityR abilityRecord->missionAffinity_ = abilityRequest.want.GetStringParam(PARAM_MISSION_AFFINITY_KEY); auto userId = abilityRequest.appInfo.uid / BASE_USER_RANGE; - if ((userId == 0 || - AppUtils::GetInstance().InResidentWhiteList(abilityRequest.abilityInfo.bundleName)) && + if ((userId == 0 || AppUtils::GetInstance().InResidentWhiteList(abilityRequest.abilityInfo.bundleName)) && DelayedSingleton::GetInstance()->IsResidentAbility( abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name, userId)) { abilityRecord->keepAliveBundle_ = true; @@ -340,7 +340,7 @@ void AbilityRecord::LoadUIAbility() g_addLifecycleEventTask(token_, methodName); } -int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide) +int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide, sptr callback) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::ABILITYMGR, "LoadLifecycle: abilityName:%{public}s", abilityInfo_.name.c_str()); @@ -382,7 +382,7 @@ int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide) MainElementUtils::SetMainUIAbilityKeepAliveFlag(isMainUIAbility, abilityInfo_.bundleName, loadParam); auto result = DelayedSingleton::GetInstance()->LoadAbility( - loadParam, abilityInfo_, abilityInfo_.applicationInfo, want_); + loadParam, abilityInfo_, abilityInfo_.applicationInfo, want_, callback); want_.RemoveParam(IS_HOOK); want_.RemoveParam(ABILITY_OWNER_USERID); want_.RemoveParam(Want::PARAMS_REAL_CALLER_KEY); @@ -491,7 +491,8 @@ void AbilityRecord::ForegroundUIExtensionAbility(uint32_t sceneFlag) } void AbilityRecord::ProcessForegroundAbility( - uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide) + uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide, + sptr callback) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); std::string element = GetElementName().GetURI(); @@ -505,7 +506,7 @@ void AbilityRecord::ProcessForegroundAbility( if (!isReady_) { TAG_LOGD(AAFwkTag::ABILITYMGR, "To load ability."); lifeCycleStateInfo_.sceneFlagBak = sceneFlag; - LoadAbility(isShellCall, isStartupHide); + LoadAbility(isShellCall, isStartupHide, callback); return; } diff --git a/services/abilitymgr/src/app_scheduler.cpp b/services/abilitymgr/src/app_scheduler.cpp index 59db683ffaea11e667757e0b0e686997c8e45ff5..6679214022a4fbfe5c74e9b308e318f576ef08e9 100644 --- a/services/abilitymgr/src/app_scheduler.cpp +++ b/services/abilitymgr/src/app_scheduler.cpp @@ -68,7 +68,8 @@ bool AppScheduler::Init(const std::weak_ptr &callback) } int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam &loadParam, const AppExecFwk::AbilityInfo &abilityInfo, - const AppExecFwk::ApplicationInfo &applicationInfo, const Want &want) + const AppExecFwk::ApplicationInfo &applicationInfo, const Want &want, + sptr callback) { if (AppUtils::GetInstance().IsForbidStart()) { TAG_LOGW(AAFwkTag::ABILITYMGR, "forbid start: %{public}s", abilityInfo.bundleName.c_str()); @@ -80,7 +81,7 @@ int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam &loadParam, const /* because the errcode type of AppMgr Client API will be changed to int, * so must to covert the return result */ int ret = static_cast(IN_PROCESS_CALL( - appMgrClient_->LoadAbility(abilityInfo, applicationInfo, want, loadParam))); + appMgrClient_->LoadAbility(abilityInfo, applicationInfo, want, loadParam, callback))); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::SERVICE_EXT, "AppScheduler fail to LoadAbility. ret %{public}d", ret); return INNER_ERR; diff --git a/services/abilitymgr/src/process_options.cpp b/services/abilitymgr/src/process_options.cpp index f2b3780be35051dc518f1b207bf85ddec1162fc5..353d89fec46777bcddbc79ed2e65216e536d1976 100644 --- a/services/abilitymgr/src/process_options.cpp +++ b/services/abilitymgr/src/process_options.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 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 @@ -27,6 +27,7 @@ bool ProcessOptions::ReadFromParcel(Parcel &parcel) isRestartKeepAlive = parcel.ReadBool(); isStartFromNDK = parcel.ReadBool(); isPreloadStart = parcel.ReadBool(); + shouldReturnPid = parcel.ReadBool(); return true; } @@ -71,6 +72,10 @@ bool ProcessOptions::Marshalling(Parcel &parcel) const TAG_LOGE(AAFwkTag::ABILITYMGR, "isPreloadStart write failed"); return false; } + if (!parcel.WriteBool(shouldReturnPid)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "shouldReturnPid write failed"); + return false; + } return true; } diff --git a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp index 4655b2331450c2ff0e12bf85631a6ff77146a1e3..d483afe3e49e585e3345dcb87723a99a64df6284 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -203,8 +203,10 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp return ERR_OK; } - if (preloadStartCheck) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "scb call, preload start"); + bool shouldReturnPid = sessionInfo->processOptions != nullptr && sessionInfo->processOptions->shouldReturnPid; + if (preloadStartCheck || shouldReturnPid) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "scb call, preloadStartCheck=%{public}d,shouldReturnPid=%{public}d", + preloadStartCheck, shouldReturnPid); abilityRequest.processOptions = sessionInfo->processOptions; } auto isCallBySCB = sessionInfo->want.GetBoolParam(ServerConstant::IS_CALL_BY_SCB, true); @@ -267,7 +269,8 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp if (abilityRequest.processOptions) { isStartupHide = abilityRequest.processOptions->startupVisibility == StartupVisibility::STARTUP_HIDE; } - uiAbilityRecord->ProcessForegroundAbility(callerTokenId, sceneFlag, isShellCall, isStartupHide); + sptr callback = GetLoadAbilityCallback(sessionInfo->requestId); + uiAbilityRecord->ProcessForegroundAbility(callerTokenId, sceneFlag, isShellCall, isStartupHide, callback); if (uiAbilityRecord->GetSpecifiedFlag().empty() && !sessionInfo->specifiedFlag.empty()) { TAG_LOGI(AAFwkTag::ABILITYMGR, "update specified: %{public}d--%{public}s", sessionInfo->requestId, sessionInfo->specifiedFlag.c_str()); @@ -277,6 +280,18 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp return ERR_OK; } +sptr UIAbilityLifecycleManager::GetLoadAbilityCallback(int32_t requestId) +{ + sptr callback = nullptr; + auto iter = loadAbilityCallbackMap_.find(requestId); + if (iter != loadAbilityCallbackMap_.end()) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "find loadability callback, requestId: %{public}d", requestId); + callback = iter->second; + loadAbilityCallbackMap_.erase(iter); + } + return callback; +} + std::shared_ptr UIAbilityLifecycleManager::GenerateAbilityRecord(AbilityRequest &abilityRequest, sptr sessionInfo, bool &isColdStart) { @@ -1415,7 +1430,8 @@ int UIAbilityLifecycleManager::CallAbilityLocked(const AbilityRequest &abilityRe return NotifySCBPendingActivation(sessionInfo, abilityRequest, errMsg); } uiAbilityRecord->SetPendingState(AbilityState::FOREGROUND); - uiAbilityRecord->ProcessForegroundAbility(sessionInfo->callingTokenId); + sptr callback = GetLoadAbilityCallback(requestId); + uiAbilityRecord->ProcessForegroundAbility(sessionInfo->callingTokenId, 0, false, false, callback); return NotifySCBPendingActivation(sessionInfo, abilityRequest, errMsg); } else { if ((persistentId != 0) && abilityRequest.want.GetBoolParam(IS_CALLING_FROM_DMS, false)) { @@ -1513,7 +1529,7 @@ void UIAbilityLifecycleManager::CallUIAbilityBySCB(const sptr &sess } sptr UIAbilityLifecycleManager::CreateSessionInfo(const AbilityRequest &abilityRequest, - int32_t requestId) const + int32_t requestId) { TAG_LOGD(AAFwkTag::ABILITYMGR, "Create session."); sptr sessionInfo = new SessionInfo(); @@ -1530,6 +1546,12 @@ sptr UIAbilityLifecycleManager::CreateSessionInfo(const AbilityRequ sessionInfo->callingTokenId = static_cast(abilityRequest.want.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, IPCSkeleton::GetCallingTokenID())); sessionInfo->instanceKey = abilityRequest.want.GetStringParam(Want::APP_INSTANCE_KEY); + if (abilityRequest.startOptions.loadAbilityCallback_ != nullptr) { + auto callback = iface_cast(abilityRequest.startOptions.loadAbilityCallback_); + if (callback != nullptr) { + loadAbilityCallbackMap_.emplace(requestId, callback); + } + } return sessionInfo; } @@ -3963,8 +3985,9 @@ bool UIAbilityLifecycleManager::HandleColdAcceptWantDone(const AAFwk::Want &want UpdateSpecifiedFlag(uiAbilityRecord, flag); uiAbilityRecord->SetSpecifiedFlag(flag); auto isShellCall = specifiedRequest.abilityRequest.want.GetBoolParam(IS_SHELL_CALL, false); + sptr callback = GetLoadAbilityCallback(specifiedRequest.requestId); uiAbilityRecord->ProcessForegroundAbility(specifiedRequest.callingTokenId, - specifiedRequest.sceneFlag, isShellCall); + specifiedRequest.sceneFlag, isShellCall, callback); SendKeyEvent(specifiedRequest.abilityRequest); return true; } diff --git a/services/abilitymgr/src/start_options.cpp b/services/abilitymgr/src/start_options.cpp index 33e384b97e41bb3d88874e303c6922c2b9b3a094..ece65b195d5e1e6ed838cd936395448753c223a6 100644 --- a/services/abilitymgr/src/start_options.cpp +++ b/services/abilitymgr/src/start_options.cpp @@ -52,6 +52,7 @@ StartOptions::StartOptions(const StartOptions &other) supportWindowModes_ = other.supportWindowModes_; requestId_ = other.requestId_; windowCreateParams_ = other.windowCreateParams_; + loadAbilityCallback_ = other.loadAbilityCallback_; } StartOptions &StartOptions::operator=(const StartOptions &other) @@ -83,6 +84,7 @@ StartOptions &StartOptions::operator=(const StartOptions &other) supportWindowModes_ = other.supportWindowModes_; requestId_ = other.requestId_; windowCreateParams_ = other.windowCreateParams_; + loadAbilityCallback_ = other.loadAbilityCallback_; } return *this; } diff --git a/services/abilitymgr/src/utils/start_options_utils.cpp b/services/abilitymgr/src/utils/start_options_utils.cpp index e856d4a773306d4c8f3454eaad0094c360d0efef..5b18907d6e96729c7d58fb19e0966ca9ba44c418 100644 --- a/services/abilitymgr/src/utils/start_options_utils.cpp +++ b/services/abilitymgr/src/utils/start_options_utils.cpp @@ -112,6 +112,11 @@ int32_t StartOptionsUtils::CheckStartSelfUIAbilityStartOptions(const Want &want, CHECK_TRUE_RETURN_RET(!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() || !isEnable, ERR_CAPABILITY_NOT_SUPPORT, "not support process options"); + if (options.processOptions->startupVisibility == StartupVisibility::UNSPECIFIED && + options.processOptions->shouldReturnPid) { + return ERR_OK; + } + auto uiAbilityManager = DelayedSingleton::GetInstance()->GetUIAbilityManagerByUid( IPCSkeleton::GetCallingUid()); CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE); diff --git a/services/appmgr/include/ams_mgr_scheduler.h b/services/appmgr/include/ams_mgr_scheduler.h index 54880a748f8b8d3cb520f563bfdcc3718c4919c9..b1394ec0722813a0827c62b88e968fc54f9c7e81 100644 --- a/services/appmgr/include/ams_mgr_scheduler.h +++ b/services/appmgr/include/ams_mgr_scheduler.h @@ -49,10 +49,12 @@ public: * @param abilityInfo, the ability information. * @param appInfo, the app information. * @param want, the starting information. + * @param callback, the callback to get process id. */ virtual void LoadAbility(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const std::shared_ptr &want, std::shared_ptr loadParam) override; + const std::shared_ptr &want, std::shared_ptr loadParam, + sptr callback = nullptr) override; /** * TerminateAbility, call TerminateAbility() through the proxy object, terminate the token ability. diff --git a/services/appmgr/include/app_mgr_service_inner.h b/services/appmgr/include/app_mgr_service_inner.h index 8ecd6ea530dade12a7b72d5f5c41c9c15296d487..30ece18d74d9f1bab95b034a0712478f53459845 100644 --- a/services/appmgr/include/app_mgr_service_inner.h +++ b/services/appmgr/include/app_mgr_service_inner.h @@ -61,6 +61,7 @@ #include "iapp_state_callback.h" #include "iapplication_state_observer.h" #include "iconfiguration_observer.h" +#include "iload_ability_callback.h" #include "iremote_object.h" #include "irender_state_observer.h" #include "istart_specified_ability_response.h" @@ -101,6 +102,14 @@ class WindowPidVisibilityChangedListener; using LoadAbilityTaskFunc = std::function; constexpr int32_t BASE_USER_RANGE = 200000; +struct LoadAbilityCallbackGuard { + sptr callback_ = nullptr; + std::shared_ptr appRecord_ = nullptr; + + LoadAbilityCallbackGuard(sptr callback) : callback_(callback) {} + ~LoadAbilityCallbackGuard(); +}; + class AppMgrServiceInner : public std::enable_shared_from_this { public: struct ConfigurationObserverWithUserId { @@ -127,11 +136,13 @@ public: * @param abilityInfo, the ability information. * @param appInfo, the app information. * @param want the ability want. + * @param callback, the callback to get process id. * * @return */ virtual void LoadAbility(std::shared_ptr abilityInfo, std::shared_ptr appInfo, - std::shared_ptr want, std::shared_ptr loadParam); + std::shared_ptr want, std::shared_ptr loadParam, + sptr callback = nullptr); /** * TerminateAbility, terminate the token ability. diff --git a/services/appmgr/src/ams_mgr_scheduler.cpp b/services/appmgr/src/ams_mgr_scheduler.cpp index 329df9814c888d122714d78c42dd5ecb9577076f..1e4a68c9f046baf65524c2af87ec54752ef6d226 100644 --- a/services/appmgr/src/ams_mgr_scheduler.cpp +++ b/services/appmgr/src/ams_mgr_scheduler.cpp @@ -68,7 +68,8 @@ AmsMgrScheduler::~AmsMgrScheduler() void AmsMgrScheduler::LoadAbility(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const std::shared_ptr &want, std::shared_ptr loadParam) + const std::shared_ptr &want, std::shared_ptr loadParam, + sptr callback) { if (!abilityInfo || !appInfo) { TAG_LOGE(AAFwkTag::APPMGR, "param error"); @@ -87,8 +88,8 @@ void AmsMgrScheduler::LoadAbility(const std::shared_ptr &abilityInf TAG_LOGI(AAFwkTag::APPMGR, "SubmitLoadTask: %{public}s-%{public}s", abilityInfo->bundleName.c_str(), abilityInfo->name.c_str()); std::function loadAbilityFunc = [amsMgrServiceInner = amsMgrServiceInner_, - abilityInfo, appInfo, want, loadParam]() { - amsMgrServiceInner->LoadAbility(abilityInfo, appInfo, want, loadParam); + abilityInfo, appInfo, want, loadParam, callback]() { + amsMgrServiceInner->LoadAbility(abilityInfo, appInfo, want, loadParam, callback); }; // cache other application load ability task before scene board attach diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index aecfef532fb81405c880fb4b050e8d8189516130..9a5c544c4563842791c067adc22d06e2fe16bb53 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -871,9 +871,25 @@ void AppMgrServiceInner::ReportEventToRSS(const AppExecFwk::AbilityInfo &ability }); } +LoadAbilityCallbackGuard::~LoadAbilityCallbackGuard() +{ + if (callback_ == nullptr) { + return; + } + if (appRecord_ == nullptr || appRecord_->GetPriorityObject() == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "loadability failed"); + callback_->OnFinish(-1); + return; + } + TAG_LOGI(AAFwkTag::APPMGR, "loadability callback, pid:%{public}d", appRecord_->GetPriorityObject()->GetPid()); + callback_->OnFinish(appRecord_->GetPriorityObject()->GetPid()); +} + void AppMgrServiceInner::LoadAbility(std::shared_ptr abilityInfo, std::shared_ptr appInfo, - std::shared_ptr want, std::shared_ptr loadParam) + std::shared_ptr want, std::shared_ptr loadParam, + sptr callback) { + LoadAbilityCallbackGuard guard(callback); if (AAFwk::AppUtils::GetInstance().IsForbidStart()) { TAG_LOGW(AAFwkTag::APPMGR, "forbid start: %{public}s", abilityInfo ? abilityInfo->bundleName.c_str() : ""); return; @@ -1054,6 +1070,7 @@ void AppMgrServiceInner::LoadAbility(std::shared_ptr abilityInfo, s } want->RemoveParam(UIEXTENSION_BIND_ABILITY_ID); } + guard.appRecord_ = appRecord; AfterLoadAbility(appRecord, abilityInfo, loadParam); } diff --git a/test/mock/mock_appmgr_service/include/mock_app_mgr_service_inner.h b/test/mock/mock_appmgr_service/include/mock_app_mgr_service_inner.h index bd772cbfae9e8656a34c689ceaa647b372f25461..7fba21931b8f9af848e3255f087ae0afd92f6fb7 100644 --- a/test/mock/mock_appmgr_service/include/mock_app_mgr_service_inner.h +++ b/test/mock/mock_appmgr_service/include/mock_app_mgr_service_inner.h @@ -30,8 +30,9 @@ public: virtual ~MockAppMgrServiceInner() {} - MOCK_METHOD4(LoadAbility, void(std::shared_ptr abilityInfo, std::shared_ptr appInfo, - std::shared_ptr want, std::shared_ptr loadParam)); + MOCK_METHOD5(LoadAbility, void(std::shared_ptr abilityInfo, std::shared_ptr appInfo, + std::shared_ptr want, std::shared_ptr loadParam, + sptr callback)); MOCK_METHOD2(AttachApplication, void(const pid_t pid, const sptr& app)); MOCK_METHOD1(ApplicationForegrounded, void(const int32_t recordId)); MOCK_METHOD1(ApplicationBackgrounded, void(const int32_t recordId)); diff --git a/test/mock/services_abilitymgr_test/include/mock_app_mgr_client.h b/test/mock/services_abilitymgr_test/include/mock_app_mgr_client.h index 241c47ba8b1edb97a66a274b8384b6272f74c6e7..fb71b1946ae22a9440b0f74252e7164741b76ca1 100644 --- a/test/mock/services_abilitymgr_test/include/mock_app_mgr_client.h +++ b/test/mock/services_abilitymgr_test/include/mock_app_mgr_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -30,7 +30,7 @@ public: virtual ~MockAppMgrClient() {}; virtual AppMgrResultCode LoadAbility(const AbilityInfo &abilityInfo, const ApplicationInfo &appInfo, - const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam) + const AAFwk::Want &want, AbilityRuntime::LoadParam loadParam, sptr callback) { TAG_LOGI(AAFwkTag::TEST, "MockAppMgrClient LoadAbility enter."); token_ = loadParam.token; diff --git a/test/mock/services_abilitymgr_test/libs/aakit/include/mock_load_ability_callback.h b/test/mock/services_abilitymgr_test/libs/aakit/include/mock_load_ability_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..beace93518713d2fce93d904ec05ca99cc57368f --- /dev/null +++ b/test/mock/services_abilitymgr_test/libs/aakit/include/mock_load_ability_callback.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 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 MOCK_OHOS_ABILITY_RUNTIME_MOCK_LOAD_ABILITY_CALLBACK_H +#define MOCK_OHOS_ABILITY_RUNTIME_MOCK_LOAD_ABILITY_CALLBACK_H + +#include "load_ability_callback_stub.h" + +namespace OHOS { +namespace AbilityRuntime { +class MockLoadAbilityCallback : public AppExecFwk::LoadAbilityCallbackStub { +public: + MockLoadAbilityCallback() {}; + virtual ~MockLoadAbilityCallback() {}; + virtual void OnFinish(int32_t pid) override; +}; +} // namespace AAFwk +} // namespace OHOS + +#endif // MOCK_OHOS_ABILITY_RUNTIME_MOCK_LOAD_ABILITY_CALLBACK_H diff --git a/test/mock/services_abilitymgr_test/libs/aakit/src/mock_load_ability_callback.cpp b/test/mock/services_abilitymgr_test/libs/aakit/src/mock_load_ability_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e46a32efc3565cce3275fe594c329df45c78ffc2 --- /dev/null +++ b/test/mock/services_abilitymgr_test/libs/aakit/src/mock_load_ability_callback.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 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 "mock_load_ability_callback.h" +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AbilityRuntime { +void MockLoadAbilityCallback::OnFinish(int32_t __attribute__((unused)) pid) +{ + TAG_LOGD(AAFwkTag::TEST, "mock MockLoadAbilityCallback::OnFinish"); +} +} // namespace AAFwk +} // namespace OHOS diff --git a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp index 25e8f2e6f963ee7c35e2053e82ec9bc69b072bb6..ec0d07af809b50274ed2e5cd3fe22c1b18f0fa19 100644 --- a/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp +++ b/test/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp @@ -42,7 +42,8 @@ bool AppScheduler::Init(const std::weak_ptr& callback) } int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam &loadParam, const AppExecFwk::AbilityInfo& abilityInfo, - const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want) + const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want, + sptr callback) { TAG_LOGI(AAFwkTag::TEST, "Test AppScheduler::LoadAbility()"); if (applicationInfo.bundleName.find("com.ix.First.Test") != std::string::npos) { diff --git a/test/mock/services_appmgr_test/include/mock_ams_mgr_scheduler.h b/test/mock/services_appmgr_test/include/mock_ams_mgr_scheduler.h index 5a8c6a0b8477cb2a2a9517f813bd2a96685b4c82..ced6f904f28699209e120de1c8a2629a638670c9 100644 --- a/test/mock/services_appmgr_test/include/mock_ams_mgr_scheduler.h +++ b/test/mock/services_appmgr_test/include/mock_ams_mgr_scheduler.h @@ -26,9 +26,10 @@ struct LoadParam; namespace AppExecFwk { class MockAmsMgrScheduler : public AmsMgrStub { public: - MOCK_METHOD4(LoadAbility, + MOCK_METHOD5(LoadAbility, void(const std::shared_ptr& abilityInfo, const std::shared_ptr& appInfo, - const std::shared_ptr& want, std::shared_ptr loadParam)); + const std::shared_ptr& want, std::shared_ptr loadParam, + sptr callback)); MOCK_METHOD2(TerminateAbility, void(const sptr& token, bool clearMissionFlag)); MOCK_METHOD2(UpdateAbilityState, void(const sptr& token, const AbilityState state)); MOCK_METHOD0(Reset, void()); diff --git a/test/mock/services_appmgr_test/include/mock_app_mgr_service_inner.h b/test/mock/services_appmgr_test/include/mock_app_mgr_service_inner.h index 2a19a57600bf4e43912f3cdcba435427988bcbf2..b9362eda98d9dd329ed27af7ed9cf79040a89e05 100644 --- a/test/mock/services_appmgr_test/include/mock_app_mgr_service_inner.h +++ b/test/mock/services_appmgr_test/include/mock_app_mgr_service_inner.h @@ -32,8 +32,9 @@ public: virtual ~MockAppMgrServiceInner() {} - MOCK_METHOD4(LoadAbility, void(std::shared_ptr abilityInfo, std::shared_ptr appInfo, - std::shared_ptr want, std::shared_ptr loadParam)); + MOCK_METHOD5(LoadAbility, void(std::shared_ptr abilityInfo, std::shared_ptr appInfo, + std::shared_ptr want, std::shared_ptr loadParam, + sptr callback)); MOCK_METHOD2(AttachApplication, void(const pid_t pid, const sptr& app)); MOCK_METHOD1(ApplicationForegrounded, void(const int32_t recordId)); MOCK_METHOD1(ApplicationBackgrounded, void(const int32_t recordId)); diff --git a/test/moduletest/ability_manager_client_test/ability_manager_client_test.cpp b/test/moduletest/ability_manager_client_test/ability_manager_client_test.cpp index 91f7e42f117ce2a600f43825b7b6e2a95b36dff5..9b53ebd5c20ed530d734580218b51101c4189cda 100644 --- a/test/moduletest/ability_manager_client_test/ability_manager_client_test.cpp +++ b/test/moduletest/ability_manager_client_test/ability_manager_client_test.cpp @@ -358,6 +358,22 @@ HWTEST_F(AbilityManagerClientTest, StartSelfUIAbilityWithStartOptions_0100, Test TAG_LOGI(AAFwkTag::TEST, "StartSelfUIAbilityWithStartOptions_0100 end"); } +/** + * @tc.name: AbilityManagerClient_StartSelfUIAbilityWithPidResult_0100 + * @tc.desc: StartSelfUIAbilityWithPidResult + * @tc.type: FUNC + */ +HWTEST_F(AbilityManagerClientTest, StartSelfUIAbilityWithPidResult_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "StartSelfUIAbilityWithPidResult_0100 start"); + AAFwk::Want want; + AAFwk::StartOptions options; + auto result = AbilityManagerClient::GetInstance()->StartSelfUIAbilityWithPidResult(want, options, nullptr); + sptr token_(new IPCObjectStub()); + AbilityManagerClient::GetInstance()->SubmitSaveRecoveryInfo(token_); + EXPECT_EQ(result, ERR_OK); + TAG_LOGI(AAFwkTag::TEST, "StartSelfUIAbilityWithPidResult_0100 end"); +} /** * @tc.name: AddQueryERMSObserver_0100 * @tc.name: AbilityManagerClient_AddQueryERMSObserver_0100 diff --git a/test/moduletest/mock/include/mock_app_mgr_client.h b/test/moduletest/mock/include/mock_app_mgr_client.h index 04408b97aa3a2c2832dfbf84e817b03d673d0925..56b2f0e75007149543fb55e280ce5dd81551c36b 100644 --- a/test/moduletest/mock/include/mock_app_mgr_client.h +++ b/test/moduletest/mock/include/mock_app_mgr_client.h @@ -26,8 +26,8 @@ class MockAppMgrClient : public AppMgrClient { public: MockAppMgrClient(); ~MockAppMgrClient(); - MOCK_METHOD4(LoadAbility, AppMgrResultCode(const AbilityInfo&, const ApplicationInfo&, - const AAFwk::Want&, AbilityRuntime::LoadParam)); + MOCK_METHOD5(LoadAbility, AppMgrResultCode(const AbilityInfo&, const ApplicationInfo&, + const AAFwk::Want&, AbilityRuntime::LoadParam, sptr)); MOCK_METHOD2(TerminateAbility, AppMgrResultCode(const sptr&, bool)); MOCK_METHOD2(UpdateAbilityState, AppMgrResultCode(const sptr& token, const AbilityState state)); MOCK_METHOD3(KillApplication, AppMgrResultCode(const std::string&, const bool clearPageStack, int32_t)); diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 4f5111ade05bbae953cbfb6bf43466f6bfea4a54..030d52f22800ca54c4a0abf80f0ea4e9d759c70d 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -396,6 +396,7 @@ group("unittest") { "kiosk_manager_test:unittest", "lifecycle_deal_test:unittest", "lifecycle_test:unittest", + "load_ability_callback_impl_test:unittest", "local_pending_want_test:unittest", "local_want_agent_info_test:unittest", "main_element_utils_test:unittest", diff --git a/test/unittest/ability_manager_proxy_third_test/BUILD.gn b/test/unittest/ability_manager_proxy_third_test/BUILD.gn index 0d9b9756c8a623a17c37adea9681274d066ca367..0b46fba2e80d47358616ae3eabf7c34e09287dc9 100644 --- a/test/unittest/ability_manager_proxy_third_test/BUILD.gn +++ b/test/unittest/ability_manager_proxy_third_test/BUILD.gn @@ -30,6 +30,7 @@ ohos_unittest("ability_manager_proxy_third_test") { sources = [ "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/appexecfwk_core/src/appmgr/mock_app_scheduler.cpp", + "${ability_runtime_test_path}/mock/services_abilitymgr_test/libs/aakit/src/mock_load_ability_callback.cpp", "ability_manager_proxy_third_test.cpp", ] diff --git a/test/unittest/ability_manager_proxy_third_test/ability_manager_proxy_third_test.cpp b/test/unittest/ability_manager_proxy_third_test/ability_manager_proxy_third_test.cpp index dbb3019efdf0c61781356e156e020a217825e230..386a6f2e486655347c8cdfb1dec27d926b8072bb 100644 --- a/test/unittest/ability_manager_proxy_third_test/ability_manager_proxy_third_test.cpp +++ b/test/unittest/ability_manager_proxy_third_test/ability_manager_proxy_third_test.cpp @@ -27,6 +27,7 @@ #include "mission_snapshot.h" #include "mock_ability_connect_callback.h" #include "mock_ability_token.h" +#include "mock_load_ability_callback.h" #include "want_sender_info.h" using namespace testing::ext; @@ -186,13 +187,13 @@ HWTEST_F(AbilityManagerProxyTest, StartSelfUIAbility_0100, TestSize.Level1) } /** - * @tc.name: StartSelfUIAbilityWithStartOptions_0200 + * @tc.name: StartSelfUIAbilityWithStartOptions_0100 * @tc.desc: StartSelfUIAbilityWithStartOptions * @tc.type: FUNC */ -HWTEST_F(AbilityManagerProxyTest, StartSelfUIAbilityWithStartOptions_0200, TestSize.Level1) +HWTEST_F(AbilityManagerProxyTest, StartSelfUIAbilityWithStartOptions_0100, TestSize.Level1) { - GTEST_LOG_(INFO) << "StartSelfUIAbilityWithStartOptions_0200 start"; + GTEST_LOG_(INFO) << "StartSelfUIAbilityWithStartOptions_0100 start"; EXPECT_CALL(*mock_, SendRequest(_, _, _, _)) .Times(1) @@ -212,7 +213,38 @@ HWTEST_F(AbilityManagerProxyTest, StartSelfUIAbilityWithStartOptions_0200, TestS static_cast(AbilityManagerInterfaceCode::START_SELF_UI_ABILITY_WITH_START_OPTIONS), mock_->code_); EXPECT_EQ(result, NO_ERROR); - GTEST_LOG_(INFO) << "StartSelfUIAbilityWithStartOptions_0200 end"; + GTEST_LOG_(INFO) << "StartSelfUIAbilityWithStartOptions_0100 end"; +} + +/** + * @tc.name: StartSelfUIAbilityWithPidResult_0100 + * @tc.desc: StartSelfUIAbilityWithPidResult + * @tc.type: FUNC + */ +HWTEST_F(AbilityManagerProxyTest, StartSelfUIAbilityWithPidResult_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StartSelfUIAbilityWithPidResult_0100 start"; + + EXPECT_CALL(*mock_, SendRequest(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(mock_.GetRefPtr(), &AbilityManagerStubMock::InvokeErrorSendRequest)); + Want want; + StartOptions options; + sptr callback = sptr::MakeSptr(); + int32_t result = proxy_->StartSelfUIAbilityWithPidResult(want, options, callback); + EXPECT_EQ( + static_cast(AbilityManagerInterfaceCode::START_SELF_UI_ABILITY_WITH_PID_RESULT), mock_->code_); + EXPECT_NE(result, NO_ERROR); + + EXPECT_CALL(*mock_, SendRequest(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(mock_.GetRefPtr(), &AbilityManagerStubMock::InvokeSendRequest)); + result = proxy_->StartSelfUIAbilityWithPidResult(want, options, callback); + EXPECT_EQ( + static_cast(AbilityManagerInterfaceCode::START_SELF_UI_ABILITY_WITH_PID_RESULT), mock_->code_); + EXPECT_EQ(result, NO_ERROR); + + GTEST_LOG_(INFO) << "StartSelfUIAbilityWithPidResult_0100 end"; } /** diff --git a/test/unittest/ability_manager_service_fourteenth_test/mock/src/mock_ability_record.cpp b/test/unittest/ability_manager_service_fourteenth_test/mock/src/mock_ability_record.cpp index 9f259563bff921aa2a424ec3330512005fb5818e..595af525aa42f777ce71c5f14bec0fec43a4aa37 100644 --- a/test/unittest/ability_manager_service_fourteenth_test/mock/src/mock_ability_record.cpp +++ b/test/unittest/ability_manager_service_fourteenth_test/mock/src/mock_ability_record.cpp @@ -295,7 +295,7 @@ void AbilityRecord::LoadUIAbility() g_addLifecycleEventTask(token_, methodName); } -int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide) +int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide, sptr callback) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::ABILITYMGR, "LoadLifecycle: abilityName:%{public}s", abilityInfo_.name.c_str()); @@ -367,7 +367,8 @@ void AbilityRecord::ForegroundUIExtensionAbility(uint32_t sceneFlag) } void AbilityRecord::ProcessForegroundAbility( - uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide) + uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide, + sptr callback) { } diff --git a/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_ability_record.cpp b/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_ability_record.cpp index dc03e69042ab0458bf8618e82d938485890da12e..06c4b5ffa561f18b978ca022a13f0bfca2e7af65 100644 --- a/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_ability_record.cpp +++ b/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_ability_record.cpp @@ -307,7 +307,7 @@ void AbilityRecord::LoadUIAbility() g_addLifecycleEventTask(token_, methodName); } -int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide) +int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide, sptr callback) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::ABILITYMGR, "LoadLifecycle: abilityName:%{public}s", abilityInfo_.name.c_str()); @@ -379,7 +379,8 @@ void AbilityRecord::ForegroundUIExtensionAbility(uint32_t sceneFlag) } void AbilityRecord::ProcessForegroundAbility( - uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide) + uint32_t tokenId, uint32_t sceneFlag, bool isShellCall, bool isStartupHide, + sptr callback) { } diff --git a/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_app_scheduler.cpp b/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_app_scheduler.cpp index 44f449932ec4f4ef8b1b0b46278da1423096eeb2..91ad5f80fef12b38201cd23730d922cd6b94f274 100644 --- a/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_app_scheduler.cpp +++ b/test/unittest/ability_manager_service_thirteenth_test/mock/src/mock_app_scheduler.cpp @@ -41,7 +41,8 @@ bool AppScheduler::Init(const std::weak_ptr& callback) } int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam& loadParam, const AppExecFwk::AbilityInfo& abilityInfo, - const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want) + const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want, + sptr callback) { TAG_LOGI(AAFwkTag::TEST, "Test AppScheduler::LoadAbility()"); if (applicationInfo.bundleName.find("com.ix.First.Test") != std::string::npos) { diff --git a/test/unittest/ability_permission_util_second_test/mock/src/mock_app_scheduler.cpp b/test/unittest/ability_permission_util_second_test/mock/src/mock_app_scheduler.cpp index 2c3558700742b361fcbc4985a5667e0029d1a36e..66d8c840d5b2f9720f1d96c8f0d65c425a9ee99b 100644 --- a/test/unittest/ability_permission_util_second_test/mock/src/mock_app_scheduler.cpp +++ b/test/unittest/ability_permission_util_second_test/mock/src/mock_app_scheduler.cpp @@ -42,7 +42,8 @@ bool AppScheduler::Init(const std::weak_ptr& callback) } int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam& loadParam, const AppExecFwk::AbilityInfo& abilityInfo, - const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want) + const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want, + sptr callback) { TAG_LOGI(AAFwkTag::TEST, "Test AppScheduler::LoadAbility()"); if (applicationInfo.bundleName.find("com.ix.First.Test") != std::string::npos) { diff --git a/test/unittest/ams_app_mgr_client_test/ams_app_mgr_client_test.cpp b/test/unittest/ams_app_mgr_client_test/ams_app_mgr_client_test.cpp index a60326fea58773d33ff6b37608a96f7144506958..8be1d3bd1576527710911d502242cd513e5c0f78 100644 --- a/test/unittest/ams_app_mgr_client_test/ams_app_mgr_client_test.cpp +++ b/test/unittest/ams_app_mgr_client_test/ams_app_mgr_client_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -122,7 +122,7 @@ HWTEST_F(AmsAppMgrClientTest, AppMgrClient_001, TestSize.Level1) sptr amsMgrScheduler(new MockAmsMgrScheduler()); EXPECT_CALL(*(static_cast(amsMgrScheduler.GetRefPtr())), - LoadAbility(_, _, _, _)).Times(1); + LoadAbility(_, _, _, _, _)).Times(1); EXPECT_CALL(*(static_cast((iface_cast(client_->GetRemoteObject())).GetRefPtr())), GetAmsMgr()) diff --git a/test/unittest/ams_mgr_scheduler_test/ams_mgr_scheduler_test.cpp b/test/unittest/ams_mgr_scheduler_test/ams_mgr_scheduler_test.cpp index 05f2d875821c3235f608c2f1b644b7c3417496e9..4c967563353711db2d6ca5f7d1c8cdbc46094a93 100644 --- a/test/unittest/ams_mgr_scheduler_test/ams_mgr_scheduler_test.cpp +++ b/test/unittest/ams_mgr_scheduler_test/ams_mgr_scheduler_test.cpp @@ -114,7 +114,7 @@ HWTEST_F(AmsMgrSchedulerTest, AmsMgrScheduler_001, TestSize.Level1) std::shared_ptr applicationInfo = std::make_shared(); applicationInfo->name = GetTestAppName(); - EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _)) + EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _, _)) .WillOnce(InvokeWithoutArgs(mockAppMgrServiceInner.get(), &MockAppMgrServiceInner::Post)); AbilityRuntime::LoadParam loadParam; loadParam.token = new MockAbilityToken(); @@ -150,7 +150,7 @@ HWTEST_F(AmsMgrSchedulerTest, AmsMgrScheduler_002, TestSize.Level1) applicationInfo->name = GetTestAppName(); // check token parameter - EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _)).Times(0); + EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _, _)).Times(0); AbilityRuntime::LoadParam loadParam; loadParam.token = new MockAbilityToken(); loadParam.preToken = new MockAbilityToken(); @@ -158,7 +158,7 @@ HWTEST_F(AmsMgrSchedulerTest, AmsMgrScheduler_002, TestSize.Level1) amsMgrScheduler->LoadAbility(nullptr, applicationInfo, nullptr, loadParamPtr); // check pretoken parameter - EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _)).Times(0); + EXPECT_CALL(*mockAppMgrServiceInner, LoadAbility(_, _, _, _, _)).Times(0); amsMgrScheduler->LoadAbility(abilityInfo, nullptr, nullptr, loadParamPtr); TAG_LOGD(AAFwkTag::TEST, "AmsMgrScheduler_002 end."); diff --git a/test/unittest/app_exit_reason_helper_fourth_test/mock/src/mock_app_scheduler.cpp b/test/unittest/app_exit_reason_helper_fourth_test/mock/src/mock_app_scheduler.cpp index 4a27fcc3775f91130c2a15ee3a8e2620bf918f6b..923313941a64b770d082188b4cc5851e80e19bf1 100644 --- a/test/unittest/app_exit_reason_helper_fourth_test/mock/src/mock_app_scheduler.cpp +++ b/test/unittest/app_exit_reason_helper_fourth_test/mock/src/mock_app_scheduler.cpp @@ -41,7 +41,8 @@ bool AppScheduler::Init(const std::weak_ptr& callback) } int AppScheduler::LoadAbility(const AbilityRuntime::LoadParam& loadParam, const AppExecFwk::AbilityInfo& abilityInfo, - const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want) + const AppExecFwk::ApplicationInfo& applicationInfo, const AAFwk::Want& want, + sptr callback) { TAG_LOGI(AAFwkTag::TEST, "Test AppScheduler::LoadAbility()"); if (applicationInfo.bundleName.find("com.ix.First.Test") != std::string::npos) { diff --git a/test/unittest/app_scheduler_test/app_mgr_client_mock.h b/test/unittest/app_scheduler_test/app_mgr_client_mock.h index dbf55fc4cb47c645e3e44df0ba2e0d7e67d08ff9..fdf2fcfbbf4ba086da6479764c9bc540a30b7e3c 100755 --- a/test/unittest/app_scheduler_test/app_mgr_client_mock.h +++ b/test/unittest/app_scheduler_test/app_mgr_client_mock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -31,8 +31,8 @@ public: {} MOCK_METHOD0(ConnectAppMgrService, AppMgrResultCode()); MOCK_METHOD1(RegisterAppStateCallback, AppMgrResultCode(const sptr &callback)); - MOCK_METHOD4(LoadAbility, AppMgrResultCode(const AbilityInfo&, const ApplicationInfo&, - const AAFwk::Want&, AbilityRuntime::LoadParam)); + MOCK_METHOD5(LoadAbility, AppMgrResultCode(const AbilityInfo&, const ApplicationInfo&, + const AAFwk::Want&, AbilityRuntime::LoadParam, sptr)); MOCK_METHOD2(TerminateAbility, AppMgrResultCode(const sptr&, bool)); MOCK_METHOD2(UpdateExtensionState, AppMgrResultCode(const sptr &token, const ExtensionState state)); MOCK_METHOD4(UpdateApplicationInfoInstalled, AppMgrResultCode(const std::string &bundleName, const int uid, diff --git a/test/unittest/app_scheduler_test/app_scheduler_test.cpp b/test/unittest/app_scheduler_test/app_scheduler_test.cpp index 4f17e2479e20eb8e348e4bb0c5f6acacc6f93a6c..7a965adc542380139bce9d4a6d97eb0678317381 100644 --- a/test/unittest/app_scheduler_test/app_scheduler_test.cpp +++ b/test/unittest/app_scheduler_test/app_scheduler_test.cpp @@ -248,7 +248,7 @@ HWTEST_F(AppSchedulerTest, AppScheduler_oprator_004, TestSize.Level1) */ HWTEST_F(AppSchedulerTest, AppScheduler_LoadAbility_001, TestSize.Level1) { - EXPECT_CALL(*clientMock_, LoadAbility(_, _, _, _)).Times(1) + EXPECT_CALL(*clientMock_, LoadAbility(_, _, _, _, _)).Times(1) .WillOnce(Return(AppMgrResultCode::ERROR_SERVICE_NOT_READY)); sptr token; sptr preToken; diff --git a/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp b/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp index ebde4411163ace795c81a8502024346794f71f3e..e39d9a5394c68f2b694a75d6ac2c903a036b951d 100644 --- a/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp +++ b/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp @@ -2647,124 +2647,155 @@ HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToCommonBusinessErrorC } /** - * @tc.number: ConvertToAPI18BusinessErrorCode_001 - * @tc.desc: ConvertToAPI18BusinessErrorCode + * @tc.number: ConvertToAPI17BusinessErrorCode_001 + * @tc.desc: ConvertToAPI17BusinessErrorCode * @tc.type: FUNC */ -HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToAPI18BusinessErrorCode_001, TestSize.Level2) +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToAPI17BusinessErrorCode_001, TestSize.Level2) { int32_t abilityManagerError = OHOS::ERR_OK; AbilityRuntime_ErrorCode errCode = ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; abilityManagerError = OHOS::ERR_OK; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); abilityManagerError = OHOS::AAFwk::CHECK_PERMISSION_FAILED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_PERMISSION_DENIED); abilityManagerError = OHOS::ERR_PERMISSION_DENIED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_PERMISSION_DENIED); abilityManagerError = OHOS::AAFwk::ERR_CAPABILITY_NOT_SUPPORT; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NOT_SUPPORTED); abilityManagerError = OHOS::AAFwk::RESOLVE_ABILITY_ERR; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NO_SUCH_ABILITY); abilityManagerError = OHOS::AAFwk::TARGET_BUNDLE_NOT_EXIST; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NO_SUCH_ABILITY); abilityManagerError = OHOS::AAFwk::ERR_NOT_ALLOW_IMPLICIT_START; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NO_SUCH_ABILITY); abilityManagerError = OHOS::AAFwk::ERR_WRONG_INTERFACE_CALL; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INCORRECT_ABILITY_TYPE); abilityManagerError = OHOS::AAFwk::TARGET_ABILITY_NOT_SERVICE; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INCORRECT_ABILITY_TYPE); abilityManagerError = OHOS::AAFwk::RESOLVE_CALL_ABILITY_TYPE_ERR; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INCORRECT_ABILITY_TYPE); abilityManagerError = OHOS::AAFwk::ERR_CROWDTEST_EXPIRED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_CROWDTEST_EXPIRED); abilityManagerError = OHOS::ERR_WOULD_BLOCK; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_WUKONG_MODE); abilityManagerError = -1; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INTERNAL); } /** - * @tc.number: ConvertToAPI18BusinessErrorCode_002 - * @tc.desc: ConvertToAPI18BusinessErrorCode + * @tc.number: ConvertToAPI17BusinessErrorCode_002 + * @tc.desc: ConvertToAPI17BusinessErrorCode * @tc.type: FUNC */ -HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToAPI18BusinessErrorCode_002, TestSize.Level2) +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToAPI17BusinessErrorCode_002, TestSize.Level2) { int32_t abilityManagerError = OHOS::ERR_OK; AbilityRuntime_ErrorCode errCode = ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; abilityManagerError = OHOS::AAFwk::ERR_APP_CONTROLLED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_CONTROLLED); abilityManagerError = OHOS::AAFwk::ERR_EDM_APP_CONTROLLED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_EDM_CONTROLLED); abilityManagerError = OHOS::AAFwk::ERR_START_OTHER_APP_FAILED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_CROSS_APP); abilityManagerError = OHOS::AAFwk::NOT_TOP_ABILITY; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NOT_TOP_ABILITY); abilityManagerError = OHOS::AAFwk::ERR_START_OPTIONS_CHECK_FAILED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_VISIBILITY_SETTING_DISABLED); abilityManagerError = OHOS::AAFwk::ERR_UPPER_LIMIT; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_UPPER_LIMIT_REACHED); abilityManagerError = OHOS::AAFwk::ERR_APP_INSTANCE_KEY_NOT_SUPPORT; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_APP_INSTANCE_KEY_NOT_SUPPORTED); abilityManagerError = OHOS::AAFwk::ERR_NOT_SELF_APPLICATION; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_CROSS_APP); abilityManagerError = OHOS::AAFwk::ERR_MULTI_APP_NOT_SUPPORTED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_MULTI_APP_NOT_SUPPORTED); abilityManagerError = OHOS::AAFwk::ERR_INVALID_APP_INSTANCE_KEY; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INVALID_APP_INSTANCE_KEY); abilityManagerError = OHOS::AAFwk::ERR_MULTI_INSTANCE_NOT_SUPPORTED; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_MULTI_INSTANCE_NOT_SUPPORTED); abilityManagerError = -1; - errCode = ConvertToAPI18BusinessErrorCode(abilityManagerError); + errCode = ConvertToAPI17BusinessErrorCode(abilityManagerError); + EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INTERNAL); +} + +/** + * @tc.number: ConvertToAPI21BusinessErrorCode_001 + * @tc.desc: ConvertToAPI21BusinessErrorCode + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, ConvertToAPI21BusinessErrorCode_001, TestSize.Level2) +{ + int32_t abilityManagerError = OHOS::ERR_OK; + AbilityRuntime_ErrorCode errCode = ABILITY_RUNTIME_ERROR_CODE_NO_ERROR; + + abilityManagerError = OHOS::ERR_OK; + errCode = ConvertToAPI21BusinessErrorCode(abilityManagerError); + EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + + abilityManagerError = OHOS::AAFwk::CHECK_PERMISSION_FAILED; + errCode = ConvertToAPI21BusinessErrorCode(abilityManagerError); + EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_PERMISSION_DENIED); + + abilityManagerError = OHOS::AAFwk::ERR_MULTI_APP_NOT_SUPPORTED; + errCode = ConvertToAPI21BusinessErrorCode(abilityManagerError); + EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_MULTI_APP_NOT_SUPPORTED); + + abilityManagerError = OHOS::AAFwk::ERR_ATTACH_ABILITY_THREAD_FAILED; + errCode = ConvertToAPI21BusinessErrorCode(abilityManagerError); + EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_START_TIMEOUT); + + abilityManagerError = OHOS::AAFwk::ERR_WRITE_INT_FAILED; + errCode = ConvertToAPI21BusinessErrorCode(abilityManagerError); EXPECT_EQ(errCode, ABILITY_RUNTIME_ERROR_CODE_INTERNAL); } @@ -2790,4 +2821,53 @@ HWTEST_F(CapiAbilityRuntimeApplicationContextTest, GetVersionCode_001, TestSize. ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); ASSERT_EQ(versionCode, 111); } + +/** + * @tc.number: OH_AbilityRuntime_StartSelfUIAbilityWithPidResult_001 + * @tc.desc: OH_AbilityRuntime_StartSelfUIAbilityWithPidResult returns 16000134 + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_StartSelfUIAbilityWithPidResult_001, + TestSize.Level2) +{ + // Act + int32_t pid = -1; + AbilityRuntime_ErrorCode result = OH_AbilityRuntime_StartSelfUIAbilityWithPidResult(nullptr, nullptr, pid); + + // Assert + EXPECT_EQ(ABILITY_RUNTIME_ERROR_CODE_MAIN_THREAD_NOT_SUPPORTED, result); +} + +/** + * @tc.number: OH_AbilityRuntime_StartSelfUIAbilityWithPidResult_002 + * @tc.desc: OH_AbilityRuntime_StartSelfUIAbilityWithPidResult does not return ERR_OK when everything is ok + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_StartSelfUIAbilityWithPidResult_002, + TestSize.Level2) +{ + // Arrange + AbilityBase_Want want; + char bundleName[] = "com.example.myapplication"; + want.element.bundleName = bundleName; + + char abilityName[] = "com.test.Ability"; + want.element.abilityName = abilityName; + + char moduleName[] = "com.test.module"; + want.element.moduleName = moduleName; + + AbilityRuntime_StartOptions *options = OH_AbilityRuntime_CreateStartOptions(); + ASSERT_NE(options, nullptr); + + // Act + int32_t pid = -1; + AbilityRuntime_ErrorCode result = OH_AbilityRuntime_StartSelfUIAbilityWithPidResult(&want, options, pid); + + // Assert + EXPECT_NE(ABILITY_RUNTIME_ERROR_CODE_NO_ERROR, result); + + ASSERT_EQ(OH_AbilityRuntime_DestroyStartOptions(&options), ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + ASSERT_EQ(options, nullptr); +} } // namespace OHOS::AbilityRuntime diff --git a/test/unittest/frameworks_kits_ability_ability_runtime_test/mock_ability_manager_client.cpp b/test/unittest/frameworks_kits_ability_ability_runtime_test/mock_ability_manager_client.cpp index 2fc6738d5322664857763fc448e80317095b9267..9fc866572d4696cb6c0c8523136c6c63fed240a8 100644 --- a/test/unittest/frameworks_kits_ability_ability_runtime_test/mock_ability_manager_client.cpp +++ b/test/unittest/frameworks_kits_ability_ability_runtime_test/mock_ability_manager_client.cpp @@ -1043,6 +1043,12 @@ ErrCode AbilityManagerClient::StartSelfUIAbilityWithStartOptions(const Want &wan return ERR_OK; } +int AbilityManagerClient::StartSelfUIAbilityWithPidResult(const Want &want, StartOptions &options, + sptr callback) +{ + return ERR_OK; +} + void AbilityManagerClient::PrepareTerminateAbilityDone(sptr token, bool isTerminate) {} diff --git a/test/unittest/load_ability_callback_impl_test/BUILD.gn b/test/unittest/load_ability_callback_impl_test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5c41215182d1343f8a720b28dbde02d8ff12080e --- /dev/null +++ b/test/unittest/load_ability_callback_impl_test/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2025 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/test.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +module_output_path = "ability_runtime/ability_runtime/abilitymgr" + +ohos_unittest("load_ability_callback_impl_test") { + module_out_path = module_output_path + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../../cfi_blocklist.txt" + } + + include_dirs = [ + "${ability_runtime_path}/frameworks/c/ability_runtime/include", + "${ability_runtime_path}/services/common/include", + ] + + sources = [ + "${ability_runtime_path}/frameworks/c/ability_runtime/src/load_ability_callback_impl.cpp", + "load_ability_callback_impl_test.cpp", + ] + + deps = [ + "${ability_runtime_innerkits_path}/app_manager:app_manager", + ] + + external_deps = [ + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] + + cflags_cc = [] + if (os_dlp_part_enabled) { + cflags_cc += [ "-DWITH_DLP" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":load_ability_callback_impl_test" ] +} diff --git a/test/unittest/load_ability_callback_impl_test/load_ability_callback_impl_test.cpp b/test/unittest/load_ability_callback_impl_test/load_ability_callback_impl_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20f5ee1b9ef2cd428ce7222c3c5c40d5ed96507c --- /dev/null +++ b/test/unittest/load_ability_callback_impl_test/load_ability_callback_impl_test.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 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 +#define private public +#define protected public +#include "load_ability_callback_impl.h" +#include "hilog_tag_wrapper.h" +#undef private +#undef protected + +using namespace testing::ext; +using namespace testing; +using namespace OHOS::AbilityRuntime; +namespace OHOS { +namespace AAFwk { +class LoadAbilityCallbackImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; +void LoadAbilityCallbackImplTest::SetUpTestCase(void) {} +void LoadAbilityCallbackImplTest::TearDownTestCase(void) {} +void LoadAbilityCallbackImplTest::TearDown() {} +void LoadAbilityCallbackImplTest::SetUp() {} + +/** + * @tc.name: LoadAbilityCallbackImplTest_OnFinish_0001 + * @tc.desc: Test the state of OnFinish + * @tc.type: FUNC + */ +HWTEST_F(LoadAbilityCallbackImplTest, OnFinish_0001, TestSize.Level1) +{ + bool called = false; + int32_t targetPid = -1; + OnFinishTask task = [&called, &targetPid](int32_t pid) { + targetPid = pid; + called = true; + }; + auto callbackImpl = std::make_shared(std::move(task)); + int32_t pid = 10000; + callbackImpl->OnFinish(pid); + EXPECT_NE(callbackImpl->task_, nullptr); + EXPECT_TRUE(called); + EXPECT_EQ(targetPid, pid); +} + +/** + * @tc.name: LoadAbilityCallbackImplTest_Cancel_0001 + * @tc.desc: Test the state of Cancel + * @tc.type: FUNC + */ +HWTEST_F(LoadAbilityCallbackImplTest, Cancel_0001, TestSize.Level1) +{ + bool called = false; + int32_t targetPid = -1; + OnFinishTask task = [&called, &targetPid](int32_t pid) { + targetPid = pid; + called = true; + }; + auto callbackImpl = std::make_shared(std::move(task)); + EXPECT_NE(callbackImpl->task_, nullptr); + + callbackImpl->Cancel(); + int32_t pid = 10000; + callbackImpl->OnFinish(pid); + EXPECT_EQ(callbackImpl->task_, nullptr); + EXPECT_FALSE(called); + EXPECT_NE(targetPid, pid); +} +} // namespace AAFwk +} // namespace OHOS diff --git a/test/unittest/start_options_utils_test/start_options_utils_test.cpp b/test/unittest/start_options_utils_test/start_options_utils_test.cpp index eabea7ce320edf94f72a58c593a5b1d7db8b1c36..1fc7be076deea86c77017465e5e0c61a98facf73 100644 --- a/test/unittest/start_options_utils_test/start_options_utils_test.cpp +++ b/test/unittest/start_options_utils_test/start_options_utils_test.cpp @@ -243,6 +243,31 @@ HWTEST_F(StartOptionsUtilsTest, CheckStartSelfUIAbilityStartOptions_006, TestSiz TAG_LOGI(AAFwkTag::TEST, "StartOptionsUtilsTest CheckStartSelfUIAbilityStartOptions_006 end"); } +/* + * Feature: StartOptionsUtils + * Function: CheckStartSelfUIAbilityStartOptions + * SubFunction: NA + * FunctionPoints: StartOptionsUtils CheckStartSelfUIAbilityStartOptions + */ +HWTEST_F(StartOptionsUtilsTest, CheckStartSelfUIAbilityStartOptions_007, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "StartOptionsUtilsTest CheckStartSelfUIAbilityStartOptions_007 start"); + + MyFlag::GetInstance().isScbEnabled_ = true; + MyFlag::GetInstance().isStartOptionsWithProcessOptions_ = true; + MyFlag::GetInstance().uiManager_ = nullptr; + + Want want; + StartOptions startOptions; + startOptions.processOptions = std::make_shared(); + startOptions.processOptions->startupVisibility = StartupVisibility::UNSPECIFIED; + startOptions.processOptions->shouldReturnPid = true; + auto ret = StartOptionsUtils::CheckStartSelfUIAbilityStartOptions(want, startOptions); + EXPECT_EQ(ret, ERR_OK); + + TAG_LOGI(AAFwkTag::TEST, "StartOptionsUtilsTest CheckStartSelfUIAbilityStartOptions_007 end"); +} + /* * Feature: StartOptionsUtils * Name: CheckProcessOptionsInner_001