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 8787784db68dd198a5d60f67de0c7eb252afd884..8cf76b351dc31a151cd40b90d134c573b1cd9608 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 @@ -328,6 +328,8 @@ public: int GetApplicationInfoByProcessID(const int pid, AppExecFwk::ApplicationInfo &application, bool &debug); + int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) const; + private: void SetServiceManager(std::unique_ptr serviceMgr); /** diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h index 034da2edba01702cfeb4f54dccf159e78c22ea3b..6c4e71978df749981dfa5a7ae35a5351806ab72d 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h @@ -332,6 +332,8 @@ public: */ virtual bool IsSharedBundleRunning(const std::string &bundleName, uint32_t versionCode) = 0; + virtual int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) = 0; + // please add new message item to the bottom in order to prevent some unexpected BUG enum class Message { APP_ATTACH_APPLICATION = 0, @@ -371,6 +373,7 @@ public: APP_GET_PROCESS_RUNNING_INFORMATION, IS_SHARED_BUNDLE_RUNNING, DUMP_HEAP_MEMORY_PROCESS, + START_NATIVE_PROCESS_FOR_DEBUGGER, }; }; } // namespace AppExecFwk diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h index 88393e4dbd9f68575f5e2a20f9758e346c658dd1..6754ac32911415f69b3223502d74b430a139ff5e 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h @@ -287,6 +287,8 @@ public: */ virtual bool IsSharedBundleRunning(const std::string &bundleName, uint32_t versionCode) override; + virtual int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) override; + private: bool SendTransactCmd(IAppMgr::Message code, MessageParcel &data, MessageParcel &reply); bool WriteInterfaceToken(MessageParcel &data); diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h index 74ef068dd1528c5c1d09452d9bfaa7b54cf7dd6e..673539a639f419952ed329ceda9b6317d8b20f65 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h @@ -97,6 +97,7 @@ private: int32_t HandleSetContinuousTaskProcess(MessageParcel &data, MessageParcel &reply); #endif int32_t HandleIsSharedBundleRunning(MessageParcel &data, MessageParcel &reply); + int32_t HandleStartNativeProcessForDebugger(MessageParcel &data, MessageParcel &reply); using AppMgrFunc = int32_t (AppMgrStub::*)(MessageParcel &data, MessageParcel &reply); std::map memberFuncMap_; 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 310dd0873a48fa18b38a7b3dbed8d4c26db88cd7..7ed6bc3d6e96c1b49ef2a4201656fc003c0a9bf3 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 @@ -589,6 +589,16 @@ int AppMgrClient::GetApplicationInfoByProcessID(const int pid, AppExecFwk::Appli return amsService->GetApplicationInfoByProcessID(pid, application, debug); } +int32_t AppMgrClient::StartNativeProcessForDebugger(const AAFwk::Want &want) const +{ + sptr service = iface_cast(mgrHolder_->GetRemoteObject()); + if (service == nullptr) { + HILOG_ERROR("service is nullptr"); + return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED; + } + return service->StartNativeProcessForDebugger(want); +} + int AppMgrClient::PreStartNWebSpawnProcess() { HILOG_INFO("PreStartNWebSpawnProcess"); diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp index 9f456bcab0c46b89c524168b6a273d36eec422e4..0c1c4dbdfbc2297a231f8fc5fc279be08a456ea5 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp @@ -1113,5 +1113,34 @@ bool AppMgrProxy::IsSharedBundleRunning(const std::string &bundleName, uint32_t return reply.ReadBool(); } + +int32_t AppMgrProxy::StartNativeProcessForDebugger(const AAFwk::Want &want) +{ + MessageParcel data; + if (!WriteInterfaceToken(data)) { + HILOG_ERROR("Write interface token failed."); + return ERR_FLATTEN_OBJECT; + } + if (!data.WriteParcelable(&want)) { + HILOG_ERROR("want write failed."); + return ERR_FLATTEN_OBJECT; + } + sptr remote = Remote(); + if (remote == nullptr) { + HILOG_ERROR("Notify unload patch, Remote is nullptr."); + return ERR_NULL_OBJECT; + } + + MessageParcel reply; + MessageOption option; + auto ret = remote->SendRequest(static_cast(IAppMgr::Message::START_NATIVE_PROCESS_FOR_DEBUGGER), + data, reply, option); + if (ret != NO_ERROR) { + HILOG_WARN("SendRequest is failed, error code: %{public}d", ret); + return ret; + } + + return reply.ReadInt32(); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp index 159d94e827b9dd23c62fed79df8012a576a87db7..d74aa83735708688932a438c0b2945f359320a11 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp @@ -112,6 +112,8 @@ AppMgrStub::AppMgrStub() &AppMgrStub::HandleNotifyUnLoadRepairPatch; memberFuncMap_[static_cast(IAppMgr::Message::IS_SHARED_BUNDLE_RUNNING)] = &AppMgrStub::HandleIsSharedBundleRunning; + memberFuncMap_[static_cast(IAppMgr::Message::START_NATIVE_PROCESS_FOR_DEBUGGER)] = + &AppMgrStub::HandleStartNativeProcessForDebugger; } AppMgrStub::~AppMgrStub() @@ -623,5 +625,22 @@ int32_t AppMgrStub::HandleIsSharedBundleRunning(MessageParcel &data, MessageParc } return NO_ERROR; } + +int32_t AppMgrStub::HandleStartNativeProcessForDebugger(MessageParcel &data, MessageParcel &reply) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + HILOG_DEBUG("function called."); + std::unique_ptr want(data.ReadParcelable()); + if (want == nullptr) { + HILOG_ERROR("want is nullptr"); + return ERR_INVALID_VALUE; + } + auto result = StartNativeProcessForDebugger(*want); + if (!reply.WriteInt32(result)) { + HILOG_ERROR("fail to write result."); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appmgr/include/app_mgr_service.h b/services/appmgr/include/app_mgr_service.h index 2df108c8b8dad833f95d66a8f1a597ae0c205dcd..e278b5cb02af3a479dd9890822b9b9b36ae135d5 100644 --- a/services/appmgr/include/app_mgr_service.h +++ b/services/appmgr/include/app_mgr_service.h @@ -283,6 +283,8 @@ public: */ virtual bool IsSharedBundleRunning(const std::string &bundleName, uint32_t versionCode) override; + virtual int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) override; + private: /** * Init, Initialize application services. diff --git a/services/appmgr/include/app_mgr_service_inner.h b/services/appmgr/include/app_mgr_service_inner.h index d2962fe34a14ae9fcd934b8e516f361e247ac1a2..a93d1fc009250fd85f236a49c60f4b07841d24d0 100644 --- a/services/appmgr/include/app_mgr_service_inner.h +++ b/services/appmgr/include/app_mgr_service_inner.h @@ -305,6 +305,8 @@ public: */ virtual bool IsSharedBundleRunning(const std::string &bundleName, uint32_t versionCode); + int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) const; + std::shared_ptr CreateAppRunningRecord( const sptr &token, const sptr &preToken, @@ -632,10 +634,10 @@ private: void MakeProcessName(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, - const HapModuleInfo &hapModuleInfo, int32_t appIndex, std::string &processName); + const HapModuleInfo &hapModuleInfo, int32_t appIndex, std::string &processName) const; - void MakeProcessName( - const std::shared_ptr &appInfo, const HapModuleInfo &hapModuleInfo, std::string &processName); + void MakeProcessName(const std::shared_ptr &appInfo, const HapModuleInfo &hapModuleInfo, + std::string &processName) const; /** * StartAbility, load the ability that needed to be started(Start on the basis of the original process). * Start on a new boot process @@ -650,6 +652,9 @@ private: const std::shared_ptr &abilityInfo, const std::shared_ptr &appRecord, const HapModuleInfo &hapModuleInfo, const std::shared_ptr &want); + int32_t StartPerfProcess(const std::shared_ptr &appRecord, const std::string& perfCmd, + const std::string& debugCmd, bool isSanboxApp) const; + /** * StartProcess, load the ability that needed to be started(Start on a new boot process). * @@ -769,7 +774,7 @@ private: void ClipStringContent(const std::regex &re, const std::string &source, std::string &afterCutStr); bool GetBundleAndHapInfo(const AbilityInfo &abilityInfo, const std::shared_ptr &appInfo, - BundleInfo &bundleInfo, HapModuleInfo &hapModuleInfo, int32_t appIndex = 0); + BundleInfo &bundleInfo, HapModuleInfo &hapModuleInfo, int32_t appIndex = 0) const; AppProcessData WrapAppProcessData(const std::shared_ptr &appRecord, const ApplicationState state); @@ -853,6 +858,7 @@ private: void SendHiSysEvent(const int32_t innerEventId, const int64_t eventId); int FinishUserTestLocked( const std::string &msg, const int64_t &resultCode, const std::shared_ptr &appRecord); + int32_t GetCurrentAccountId() const; const std::string TASK_ON_CALLBACK_DIED = "OnCallbackDiedTask"; std::vector> appStateCallbacks_; std::shared_ptr appProcessManager_; diff --git a/services/appmgr/src/app_mgr_service.cpp b/services/appmgr/src/app_mgr_service.cpp index e5d3d343e223c267e25a9db7ae0104e64b402c42..f4ac545bd7590f3c358ff892be9798acdb5b9438 100644 --- a/services/appmgr/src/app_mgr_service.cpp +++ b/services/appmgr/src/app_mgr_service.cpp @@ -679,5 +679,23 @@ bool AppMgrService::IsSharedBundleRunning(const std::string &bundleName, uint32_ } return appMgrServiceInner_->IsSharedBundleRunning(bundleName, versionCode); } + +int32_t AppMgrService::StartNativeProcessForDebugger(const AAFwk::Want &want) +{ + if (!IsReady()) { + HILOG_ERROR("AppMgrService is not ready."); + return ERR_INVALID_OPERATION; + } + auto isShellCall = AAFwk::PermissionVerification::GetInstance()->IsShellCall(); + if (!isShellCall) { + HILOG_ERROR("permission denied, only called by shell."); + return ERR_INVALID_OPERATION; + } + auto ret = appMgrServiceInner_->StartNativeProcessForDebugger(want); + if (ret != ERR_OK) { + HILOG_ERROR("debuggablePipe fail to start native process."); + } + return ret; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index 47b4e1734c1afe8992e619b9f8702dd8816999e6..02c8ccbdc2b145c04ba02a4cacc7764f913d7d60 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -45,6 +45,7 @@ #ifdef SUPPORT_GRAPHICS #include "locale_config.h" #endif +#include "os_account_manager_wrapper.h" #include "parameter.h" #include "parameters.h" #include "perf_profile.h" @@ -79,6 +80,9 @@ const std::string CLASS_NAME = "ohos.app.MainThread"; const std::string FUNC_NAME = "main"; const std::string RENDER_PARAM = "invalidparam"; const std::string COLD_START = "coldStart"; +const std::string PERF_CMD = "perfCmd"; +const std::string DEBUG_CMD = "debugCmd"; +const std::string ENTER_SANBOX = "sanboxApp"; const std::string DLP_PARAMS_INDEX = "ohos.dlp.params.index"; const std::string PERMISSION_INTERNET = "ohos.permission.INTERNET"; const std::string PERMISSION_ACCESS_BUNDLE_DIR = "ohos.permission.ACCESS_BUNDLE_DIR"; @@ -117,6 +121,7 @@ const std::string PROCESS_EXIT_EVENT_TASK = "Send Process Exit Event Task"; constexpr int32_t ROOT_UID = 0; constexpr int32_t FOUNDATION_UID = 5523; +constexpr int32_t DEFAULT_USER_ID = 0; int32_t GetUserIdByUid(int32_t uid) { @@ -186,6 +191,9 @@ void AppMgrServiceInner::LoadAbility(const sptr &token, const spt int32_t bundleIndex = (want == nullptr) ? 0 : want->GetIntParam(DLP_PARAMS_INDEX, 0); StartProcess(abilityInfo->applicationName, processName, startFlags, appRecord, appInfo->uid, appInfo->bundleName, bundleIndex, appExistFlag); + std::string perfCmd = (want == nullptr) ? "" : want->GetStringParam(PERF_CMD); + bool isSanboxApp = want->GetBoolParam(ENTER_SANBOX, false); + (void)StartPerfProcess(appRecord, perfCmd, "", isSanboxApp); } else { int32_t requestProcCode = (want == nullptr) ? 0 : want->GetIntParam(Want::PARAM_RESV_REQUEST_PROC_CODE, 0); if (requestProcCode != 0 && appRecord->GetRequestProcCode() == 0) { @@ -220,7 +228,7 @@ bool AppMgrServiceInner::CheckLoadAbilityConditions(const sptr &t void AppMgrServiceInner::MakeProcessName(const std::shared_ptr &abilityInfo, const std::shared_ptr &appInfo, const HapModuleInfo &hapModuleInfo, int32_t appIndex, - std::string &processName) + std::string &processName) const { if (!abilityInfo || !appInfo) { HILOG_ERROR("param error"); @@ -237,7 +245,7 @@ void AppMgrServiceInner::MakeProcessName(const std::shared_ptr &abi } void AppMgrServiceInner::MakeProcessName( - const std::shared_ptr &appInfo, const HapModuleInfo &hapModuleInfo, std::string &processName) + const std::shared_ptr &appInfo, const HapModuleInfo &hapModuleInfo, std::string &processName) const { if (!appInfo) { return; @@ -257,7 +265,7 @@ void AppMgrServiceInner::MakeProcessName( bool AppMgrServiceInner::GetBundleAndHapInfo(const AbilityInfo &abilityInfo, const std::shared_ptr &appInfo, BundleInfo &bundleInfo, HapModuleInfo &hapModuleInfo, - int32_t appIndex) + int32_t appIndex) const { auto bundleMgr_ = remoteClientManager_->GetBundleManager(); if (bundleMgr_ == nullptr) { @@ -1518,6 +1526,39 @@ void AppMgrServiceInner::StateChangedNotifyObserver(const AbilityStateData abili DelayedSingleton::GetInstance()->StateChangedNotifyObserver(abilityStateData, isAbility); } +int32_t AppMgrServiceInner::StartPerfProcess(const std::shared_ptr &appRecord, + const std::string& perfCmd, const std::string& debugCmd, bool isSanboxApp) const +{ + if (!remoteClientManager_->GetSpawnClient() || !appRecord) { + HILOG_ERROR("appSpawnClient or appRecord is null"); + return ERR_INVALID_OPERATION; + } + if (perfCmd.empty() && debugCmd.empty()) { + HILOG_ERROR("perfCmd is empty"); + return ERR_INVALID_OPERATION; + } + + AppSpawnStartMsg startMsg = appRecord->GetStartMsg(); + if (!perfCmd.empty()) { + startMsg.renderParam = perfCmd; + HILOG_INFO("debuggablePipe perfCmd:%{public}s", perfCmd.c_str()); + } else { + HILOG_INFO("debuggablePipe debugCmd:%{public}s", debugCmd.c_str()); + } + if (isSanboxApp) { + HILOG_INFO("debuggablePipe sandbox: true"); + } + pid_t pid = 0; + ErrCode errCode = remoteClientManager_->GetSpawnClient()->StartProcess(startMsg, pid); + if (FAILED(errCode)) { + HILOG_ERROR("failed to spawn perf process, errCode %{public}08x", errCode); + appRunningManager_->RemoveAppRunningRecordById(appRecord->GetRecordId()); + return errCode; + } + HILOG_INFO("Start perf process success, pid is %{public}d", pid); + return ERR_OK; +} + void AppMgrServiceInner::StartProcess(const std::string &appName, const std::string &processName, uint32_t startFlags, const std::shared_ptr &appRecord, const int uid, const std::string &bundleName, const int32_t bundleIndex, bool appExistFlag) @@ -3406,6 +3447,75 @@ bool AppMgrServiceInner::IsSharedBundleRunning(const std::string &bundleName, ui return false; } +int32_t AppMgrServiceInner::StartNativeProcessForDebugger(const AAFwk::Want &want) const +{ + auto&& bundleMgr = remoteClientManager_->GetBundleManager(); + if (bundleMgr == nullptr) { + HILOG_ERROR("GetBundleManager fail"); + return ERR_INVALID_OPERATION; + } + + if (appRunningManager_ == nullptr) { + HILOG_ERROR("appRunningManager_ is nullptr"); + return ERR_INVALID_OPERATION; + } + HILOG_INFO("debuggablePipe bundleName:%{public}s", want.GetElement().GetBundleName().c_str()); + HILOG_INFO("debuggablePipe moduleName:%{public}s", want.GetElement().GetModuleName().c_str()); + HILOG_INFO("debuggablePipe abilityName:%{public}s", want.GetElement().GetAbilityName().c_str()); + + auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION | + AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION | + AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA); + AbilityInfo abilityInfo; + auto userId = GetCurrentAccountId(); + IN_PROCESS_CALL_WITHOUT_RET(bundleMgr->QueryAbilityInfo(want, abilityInfoFlag, userId, abilityInfo)); + + BundleInfo bundleInfo; + HapModuleInfo hapModuleInfo; + auto appInfo = std::make_shared(abilityInfo.applicationInfo); + if (!GetBundleAndHapInfo(abilityInfo, appInfo, bundleInfo, hapModuleInfo, 0)) { + HILOG_ERROR("GetBundleAndHapInfo failed"); + return ERR_INVALID_OPERATION; + } + + std::string processName; + auto abilityInfoPtr = std::make_shared(abilityInfo); + MakeProcessName(abilityInfoPtr, appInfo, hapModuleInfo, 0, processName); + + auto&& appRecord = + appRunningManager_->CheckAppRunningRecordIsExist(appInfo->name, processName, appInfo->uid, bundleInfo); + if (appRecord == nullptr) { + HILOG_ERROR("The appRecord not found."); + return ERR_INVALID_OPERATION; + } + + bool isSanboxApp = want.GetBoolParam(ENTER_SANBOX, false); + auto&& cmd = want.GetStringParam(PERF_CMD); + if (cmd.size() == 0) { + cmd = want.GetStringParam(DEBUG_CMD); + return StartPerfProcess(appRecord, "", cmd, isSanboxApp); + } else { + return StartPerfProcess(appRecord, cmd, "", isSanboxApp); + } +} + +int32_t AppMgrServiceInner::GetCurrentAccountId() const +{ + std::vector osActiveAccountIds; + ErrCode ret = DelayedSingleton::GetInstance()-> + QueryActiveOsAccountIds(osActiveAccountIds); + if (ret != ERR_OK) { + HILOG_ERROR("QueryActiveOsAccountIds failed."); + return DEFAULT_USER_ID; + } + if (osActiveAccountIds.empty()) { + HILOG_ERROR("%{public}s, QueryActiveOsAccountIds is empty, no accounts.", __func__); + return DEFAULT_USER_ID; + } + + return osActiveAccountIds.front(); +} + void AppMgrServiceInner::SetRunningSharedBundleList(const std::string &bundleName, const std::vector baseSharedBundleInfoList) { diff --git a/services/appmgr/src/app_spawn_msg_wrapper.cpp b/services/appmgr/src/app_spawn_msg_wrapper.cpp index 8e7177550bd95141f229f60de8a8b62fde1d1cc7..a1e071cb36f769f33a14e31801f981bd8ea11a2f 100644 --- a/services/appmgr/src/app_spawn_msg_wrapper.cpp +++ b/services/appmgr/src/app_spawn_msg_wrapper.cpp @@ -63,6 +63,7 @@ bool AppSpawnMsgWrapper::AssembleMsg(const AppSpawnStartMsg &startMsg) } msg_->code = static_cast(startMsg.code); if (msg_->code == AppSpawn::ClientSocket::AppOperateCode::DEFAULT) { + // || msg_->code == AppSpawn::ClientSocket::AppOperateCode::SPAWN_NATIVE_PROCESS) { msg_->uid = startMsg.uid; msg_->gid = startMsg.gid; msg_->gidCount = startMsg.gids.size(); @@ -116,7 +117,7 @@ bool AppSpawnMsgWrapper::AssembleMsg(const AppSpawnStartMsg &startMsg) bool AppSpawnMsgWrapper::VerifyMsg(const AppSpawnStartMsg &startMsg) const { - if (startMsg.code == 0) { // 0: DEFAULT + if (startMsg.code == AppSpawn::ClientSocket::AppOperateCode::DEFAULT) { if (startMsg.uid < 0) { HILOG_ERROR("invalid uid! [%{public}d]", startMsg.uid); return false; @@ -143,7 +144,7 @@ bool AppSpawnMsgWrapper::VerifyMsg(const AppSpawnStartMsg &startMsg) const HILOG_ERROR("invalid procName!"); return false; } - } else if (startMsg.code == 1) { // 1:GET_RENDER_TERMINATION_STATUS + } else if (startMsg.code == AppSpawn::ClientSocket::AppOperateCode::GET_RENDER_TERMINATION_STATUS) { if (startMsg.pid < 0) { HILOG_ERROR("invalid pid!"); return false; diff --git a/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h b/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h index 80925e5268e34170cff8150a5cce6431ff41274b..b82cb423d9a8a9b28cbc3fb2ddf0c6bbbf13a7bd 100644 --- a/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h +++ b/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h @@ -134,6 +134,11 @@ public: return 0; }; + virtual int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) override + { + return 0; + } + virtual void RegisterAppStateCallback(const sptr& callback) { callback_ = callback; diff --git a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h index 60a2067399515585b8da73284315b366dd61529f..545da1895e1eb92800d79ee45b1a8b9ca3832344 100644 --- a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h +++ b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h @@ -82,6 +82,11 @@ public: return 0; } + virtual int32_t StartNativeProcessForDebugger(const AAFwk::Want &want) override + { + return 0; + } + virtual int FinishUserTest(const std::string& msg, const int64_t& resultCode, const std::string& bundleName) { return 0; diff --git a/test/unittest/ams_ability_running_record_test/BUILD.gn b/test/unittest/ams_ability_running_record_test/BUILD.gn index 1d7fa3776a6b0e6cc213d75017f0114f217064c0..b6b64a00f991d85cf0df3803f08adbb5e8638802 100644 --- a/test/unittest/ams_ability_running_record_test/BUILD.gn +++ b/test/unittest/ams_ability_running_record_test/BUILD.gn @@ -46,6 +46,7 @@ ohos_unittest("AmsAbilityRunningRecordTest") { deps = [ "${ability_runtime_innerkits_path}/ability_manager:ability_manager", "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", "${ability_runtime_services_path}/appmgr:libappms", "${ability_runtime_services_path}/common:event_report", diff --git a/test/unittest/ams_service_app_spawn_client_test/BUILD.gn b/test/unittest/ams_service_app_spawn_client_test/BUILD.gn index 1635a68b47aee892ed75818abd41cab58d4a22c8..12537d6458b75a2541c12f1f73291d7abc8f682d 100644 --- a/test/unittest/ams_service_app_spawn_client_test/BUILD.gn +++ b/test/unittest/ams_service_app_spawn_client_test/BUILD.gn @@ -49,6 +49,7 @@ ohos_unittest("AmsServiceAppSpawnClientTest") { deps = [ "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", "${ability_runtime_services_path}/appmgr:libappms", "${ability_runtime_services_path}/common:event_report", diff --git a/test/unittest/ams_service_event_drive_test/BUILD.gn b/test/unittest/ams_service_event_drive_test/BUILD.gn index bd4b652dc4e878adba45546d944f5664c79bacff..8018faef263ae9e2aa99edda12e7191edcf11afa 100644 --- a/test/unittest/ams_service_event_drive_test/BUILD.gn +++ b/test/unittest/ams_service_event_drive_test/BUILD.gn @@ -51,6 +51,7 @@ ohos_unittest("AmsServiceEventDriveTest") { } deps = [ "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", "${ability_runtime_services_path}/appmgr:libappms", "${ability_runtime_services_path}/common:event_report", diff --git a/test/unittest/ams_service_startup_test/BUILD.gn b/test/unittest/ams_service_startup_test/BUILD.gn index 50d5fedd57468f58bb61713eb5d2b486ca08bc18..a3bd0c356efe9e0027e3855bd93eabfe91d9035b 100644 --- a/test/unittest/ams_service_startup_test/BUILD.gn +++ b/test/unittest/ams_service_startup_test/BUILD.gn @@ -48,6 +48,7 @@ ohos_unittest("AmsServiceStartupTest") { } deps = [ "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", "${ability_runtime_services_path}/appmgr:libappms", "${ability_runtime_services_path}/common:event_report", diff --git a/test/unittest/app_running_processes_info_test/BUILD.gn b/test/unittest/app_running_processes_info_test/BUILD.gn index 9512b10732f4db9a9e18bc66fe92c4dac27ae8c6..966a44c89036bc303d45d693cefe55d0bdaade7a 100644 --- a/test/unittest/app_running_processes_info_test/BUILD.gn +++ b/test/unittest/app_running_processes_info_test/BUILD.gn @@ -46,6 +46,7 @@ ohos_unittest("AppRunningProcessesInfoTest") { deps = [ "${ability_runtime_innerkits_path}/ability_manager:ability_manager", "${ability_runtime_innerkits_path}/app_manager:app_manager", + "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/uri_permission:uri_permission_mgr", "${ability_runtime_services_path}/appmgr:libappms", "${ability_runtime_services_path}/common:event_report", diff --git a/tools/aa/include/ability_command.h b/tools/aa/include/ability_command.h index 106878b2a5091b36673b8cfef080947f09f2b772..c3d3b8623ff1a4a16afd56f61faecf81aedacde4 100644 --- a/tools/aa/include/ability_command.h +++ b/tools/aa/include/ability_command.h @@ -31,6 +31,7 @@ const std::string HELP_MSG = "usage: aa \n" " stop-service stop service with options\n" " dump dump the ability info\n" " force-stop force stop the process with bundle name\n" + " process debug ability with options\n" #ifdef ABILITY_COMMAND_FOR_TEST " test start the test framework with options\n" " ApplicationNotResponding Pass in pid with options\n" @@ -57,7 +58,7 @@ const std::string HELP_MSG_START = "usage: aa start \n" "options list:\n" " -h, --help list available commands\n" - " [-d ] -a -b [-m ] [-D] " + " [-d ] -a -b [-m ] [-p ] [-D] [-S] " " start ability with an element name\n"; const std::string HELP_MSG_STOP_SERVICE = @@ -84,6 +85,12 @@ const std::string HELP_MSG_DUMPSYS = "usage: aa dump \n" " The original -s parameter is invalid\n" " The original -m parameter is invalid\n"; +const std::string HELP_MSG_PROCESS = "usage: aa process \n" + "options list:\n" + " -h, --help list available commands\n" + " -a -b [-m ] [-p ] [-d ] [-S] " + " debug ability with an element name\n"; + const std::string HELP_MSG_TEST = "usage: aa test \n" "options list:\n" @@ -134,6 +141,9 @@ const std::string STRING_BLOCK_AMS_SERVICE_NG = "error: failed to block ams serv const std::string STRING_BLOCK_APP_SERVICE_OK = "block app service successfully."; const std::string STRING_BLOCK_APP_SERVICE_NG = "error: failed to block app service."; +const std::string STRING_START_NATIVE_PROCESS_OK = "start native process successfully."; +const std::string STRING_START_NATIVE_PROCESS_NG = "error: failed to start native process."; + const int USER_TEST_COMMAND_START_INDEX = 2; const int USER_TEST_COMMAND_PARAMS_NUM = 2; const int TIME_RATE_MS = 1000; @@ -168,6 +178,7 @@ private: ErrCode RunAsStopService(); ErrCode RunAsDumpsysCommand(); ErrCode RunAsForceStop(); + ErrCode RunAsProcessCommand(); #ifdef ABILITY_COMMAND_FOR_TEST ErrCode RunForceTimeoutForTest(); ErrCode RunAsSendAppNotRespondingProcessID(); @@ -180,6 +191,7 @@ private: sptr GetAbilityManagerService(); ErrCode MakeWantFromCmd(Want& want, std::string& windowMode); + ErrCode MakeWantForProcess(Want& want); ErrCode RunAsTestCommand(); ErrCode TestCommandError(const std::string& info); }; diff --git a/tools/aa/src/ability_command.cpp b/tools/aa/src/ability_command.cpp index c22e8ce4d529afc7d7cfd799c35ca9ead00ea9ca..a272f72b529418732275f7760c91f864e02a0ccf 100644 --- a/tools/aa/src/ability_command.cpp +++ b/tools/aa/src/ability_command.cpp @@ -19,6 +19,7 @@ #include #include #include "ability_manager_client.h" +#include "app_mgr_client.h" #include "hilog_wrapper.h" #include "iservice_registry.h" #include "mission_snapshot.h" @@ -32,13 +33,13 @@ using namespace OHOS::AppExecFwk; namespace OHOS { namespace AAFwk { namespace { -const std::string SHORT_OPTIONS = "ch:d:a:b:p:s:m:CD"; +const std::string SHORT_OPTIONS = "ch:d:a:b:p:s:m:CDS"; constexpr struct option LONG_OPTIONS[] = { {"help", no_argument, nullptr, 'h'}, {"device", required_argument, nullptr, 'd'}, {"ability", required_argument, nullptr, 'a'}, {"bundle", required_argument, nullptr, 'b'}, - {"power", required_argument, nullptr, 'p'}, + {"perf", required_argument, nullptr, 'p'}, {"setting", required_argument, nullptr, 's'}, {"module", required_argument, nullptr, 'm'}, {"cold-start", no_argument, nullptr, 'C'}, @@ -67,6 +68,16 @@ constexpr struct option LONG_OPTIONS_DUMPSYS[] = { {"client", no_argument, nullptr, 'c'}, {nullptr, 0, nullptr, 0}, }; +const std::string SHORT_OPTIONS_PROCESS = "ha:b:p:m:D:S"; +constexpr struct option LONG_OPTIONS_PROCESS[] = { + {"help", no_argument, nullptr, 'h'}, + {"ability", required_argument, nullptr, 'a'}, + {"bundle", required_argument, nullptr, 'b'}, + {"perf", required_argument, nullptr, 'p'}, + {"module", required_argument, nullptr, 'm'}, + {"debug", required_argument, nullptr, 'D'}, + {nullptr, 0, nullptr, 0}, +}; } // namespace AbilityManagerShellCommand::AbilityManagerShellCommand(int argc, char* argv[]) : ShellCommand(argc, argv, TOOL_NAME) @@ -86,6 +97,7 @@ ErrCode AbilityManagerShellCommand::CreateCommandMap() {"dump", std::bind(&AbilityManagerShellCommand::RunAsDumpsysCommand, this)}, {"force-stop", std::bind(&AbilityManagerShellCommand::RunAsForceStop, this)}, {"test", std::bind(&AbilityManagerShellCommand::RunAsTestCommand, this)}, + {"process", std::bind(&AbilityManagerShellCommand::RunAsProcessCommand, this)}, #ifdef ABILITY_COMMAND_FOR_TEST {"force-timeout", std::bind(&AbilityManagerShellCommand::RunForceTimeoutForTest, this)}, {"ApplicationNotResponding", std::bind(&AbilityManagerShellCommand::RunAsSendAppNotRespondingProcessID, this)}, @@ -642,6 +654,243 @@ ErrCode AbilityManagerShellCommand::RunAsForceStop() return result; } +ErrCode AbilityManagerShellCommand::RunAsProcessCommand() +{ + Want want; + ErrCode result = MakeWantForProcess(want); + if (result == OHOS::ERR_OK) { + auto appMgrClient = std::make_shared(); + result = appMgrClient->StartNativeProcessForDebugger(want); + if (result == OHOS::ERR_OK) { + HILOG_INFO("%{public}s", STRING_START_NATIVE_PROCESS_OK.c_str()); + resultReceiver_ = STRING_START_NATIVE_PROCESS_OK; + } else { + HILOG_INFO("%{public}s result = %{public}d", STRING_START_NATIVE_PROCESS_NG.c_str(), result); + resultReceiver_ = STRING_START_NATIVE_PROCESS_NG; + } + } else { + resultReceiver_.append(HELP_MSG_PROCESS); + result = OHOS::ERR_INVALID_VALUE; + } + + return result; +} + +ErrCode AbilityManagerShellCommand::MakeWantForProcess(Want& want) +{ + int result = OHOS::ERR_OK; + int option = -1; + int counter = 0; + std::string deviceId = ""; + std::string bundleName = ""; + std::string abilityName = ""; + std::string moduleName = ""; + std::string perfCmd = ""; + std::string debugCmd = ""; + bool isPerf = false; + bool isSanboxApp = false; + + while (true) { + counter++; + + option = getopt_long(argc_, argv_, SHORT_OPTIONS_PROCESS.c_str(), LONG_OPTIONS_PROCESS, nullptr); + + HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); + + if (optind < 0 || optind > argc_) { + return OHOS::ERR_INVALID_VALUE; + } + + if (option == -1) { + // When scanning the first argument + if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) { + // 'aa process' with no option: aa process + // 'aa process' with a wrong argument: aa process xxx + HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str()); + + resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); + result = OHOS::ERR_INVALID_VALUE; + } + break; + } + + if (option == '?') { + switch (optopt) { + case 'a': { + // 'aa process -a' with no argument + HILOG_INFO("'aa %{public}s -a' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'b': { + // 'aa process -b' with no argument + HILOG_INFO("'aa %{public}s -b' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'm': { + // 'aa process -m' with no argument + HILOG_INFO("'aa %{public}s -m' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'p': { + // 'aa process -p' with no argument + HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'D': { + // 'aa process -D' with no argument + HILOG_INFO("'aa %{public}s -D' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 0: { + // 'aa process' with an unknown option: aa process --x + // 'aa process' with an unknown option: aa process --xxx + std::string unknownOption = ""; + std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); + + HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str()); + + resultReceiver_.append(unknownOptionMsg); + result = OHOS::ERR_INVALID_VALUE; + break; + } + default: { + // 'aa process' with an unknown option: aa process -x + // 'aa process' with an unknown option: aa process -xxx + std::string unknownOption = ""; + std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); + + HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str()); + + resultReceiver_.append(unknownOptionMsg); + result = OHOS::ERR_INVALID_VALUE; + break; + } + } + break; + } + + size_t paramLength = 1024; + switch (option) { + case 'h': { + // 'aa process -h' + // 'aa process --help' + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'a': { + // 'aa process -a xxx' + // save ability name + abilityName = optarg; + break; + } + case 'b': { + // 'aa process -b xxx' + // save bundle name + bundleName = optarg; + break; + } + case 'm': { + // 'aa process -m xxx' + // save module name + moduleName = optarg; + break; + } + case 'p': { + // 'aa process -p xxx' + // save perf cmd + if (strlen(optarg) < paramLength) { + perfCmd = optarg; + isPerf = true; + } + break; + } + case 'D': { + // 'aa process -D xxx' + // save debug cmd + if (!isPerf && strlen(optarg) < paramLength) { + HILOG_INFO("debug cmd."); + debugCmd = optarg; + } + break; + } + case 'S': { + // 'aa process -S' + // enter sanbox to perform app + isSanboxApp = true; + break; + } + case 0: { + break; + } + default: { + break; + } + } + } + + if (perfCmd.empty() && debugCmd.empty()) { + HILOG_INFO("debuggablePipe aa process must contains -p or -D and param length must be less than 1024."); + result = OHOS::ERR_INVALID_VALUE; + } + + if (result == OHOS::ERR_OK) { + if (abilityName.size() == 0 || bundleName.size() == 0) { + // 'aa process -a -b [-D]' + HILOG_INFO("'aa %{public}s' without enough options.", cmd_.c_str()); + + if (abilityName.size() == 0) { + resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n"); + } + + if (bundleName.size() == 0) { + resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); + } + + result = OHOS::ERR_INVALID_VALUE; + } else { + ElementName element(deviceId, bundleName, abilityName, moduleName); + want.SetElement(element); + + if (!perfCmd.empty()) { + want.SetParam("perfCmd", perfCmd); + } + if (!debugCmd.empty()) { + want.SetParam("debugCmd", debugCmd); + } + if (isSanboxApp) { + want.SetParam("sanboxApp", isSanboxApp); + } + } + } + + return result; +} + #ifdef ABILITY_COMMAND_FOR_TEST ErrCode AbilityManagerShellCommand::RunForceTimeoutForTest() { @@ -685,9 +934,11 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& win std::string bundleName = ""; std::string abilityName = ""; std::string moduleName; + std::string perfCmd; bool isColdStart = false; bool isDebugApp = false; bool isContinuation = false; + bool isSanboxApp = false; while (true) { counter++; @@ -779,6 +1030,17 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& win result = OHOS::ERR_INVALID_VALUE; break; } + case 'p': { + // 'aa start -p' with no argument + // 'aa stop-service -p' with no argument + HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str()); + + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + + result = OHOS::ERR_INVALID_VALUE; + break; + } case 0: { // 'aa start' with an unknown option: aa start --x // 'aa start' with an unknown option: aa start --xxx @@ -860,6 +1122,14 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& win moduleName = optarg; break; } + case 'p': { + // 'aa start -p xxx' + // 'aa stop-service -p xxx' + + // save module name + perfCmd = optarg; + break; + } case 'C': { // 'aa start -C' // cold start app @@ -872,6 +1142,12 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& win isDebugApp = true; break; } + case 'S': { + // 'aa start -b -a -p -S' + // enter sanbox to perform app + isSanboxApp = true; + break; + } case 'c': { // 'aa start -c' // set ability launch reason = continuation @@ -915,6 +1191,12 @@ ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& win if (isContinuation) { want.AddFlags(Want::FLAG_ABILITY_CONTINUATION); } + if (!perfCmd.empty()) { + want.SetParam("perfCmd", perfCmd); + } + if (isSanboxApp) { + want.SetParam("sanboxApp", isSanboxApp); + } } }