!18713 merge skipAbilityStageLifeCycle into master

add skipAbilityStageLifecycle

Created-by: renjh5496
Commit-by: renjianhao
Merged-by: openharmony_ci
Description: **IssueNo**:
https://gitcode.com/openharmony/ability_ability_runtime/issues/14771
**Description**:

**稳定性自检:**
| 自检项                                                       | 自检结果  |
| ------------------------------------------------------------ | -------- |
| 涉及跨进程调用的相关操作需要抛至主线程或加锁防止并发              |          |
| 成员变量进行赋值或创建需要排查并发                               |          |
| 谨慎在lambda表达式中使用引用捕获                                |          |
| 谨慎在未经拷贝的情况下使用外部传入的string、C字符串               |          |
| map\vector\list\set等stl模板类使用时需要排查并发                |          |
| 谨慎考虑加锁范围                                               |          |
| 在IPC通信中谨慎使用同步通信方式                                 |          |
| 禁止传递this指针至其他模块或线程(特别是eventhandler任务)        |          |
| 禁止将外部传入的裸指针在内部直接构造智能指针                      |          |
| 禁止多个独立创建的智能指针管理同一地址                           |          |
| 禁止在析构函数中抛异步任务                                      |          |
| 禁止js对象在非js线程(例如在IPC线程)创建、使用或销毁             |          |
| 禁止在对外接口中未经判空直接使用外部传入的指针                    |          |
| 禁止接口返回局部变量引用                                        |          |
| 禁止在信号函数中加锁                                            |          |
| 禁止在关键流程(SA启动、应用启动等主流程)执行耗时的操作           |          |
| 禁止将同一个cpp编译在不同的so中                                 |          |

**安全编码自检:**
| 自检项                                                          | 自检结果 |
| -------------------------------------------------------------- | -------- |
| 裸指针避免通过隐式转换构造为sptr                                 |          |
| json对象在取值之前必须先判断类型,避免类型不匹配                   |          |
| 序列化时必须对传入的数组大小进行校验,避免出现超大数组              |          |
| 避免使用未明确位宽的整型,选择使用int8_t、uint8_t等类型            |          |
| 外部传入的路径要做规范化校验,对路径中的.、..、../等特殊字符严格校验 |          |
| 指针变量、表示资源描述符的变量、bool变量必须赋初值                  |          |
| readParcelable获取的对象使用前需要判空                            |          |
| 分配和释放内存的函数需要成对出现                                   |          |
| 申请内存后异常退出前需要及时进行内存释放                            |          |
| 内存申请前必须对内存大小进行合法性校验                              |          |
| 内存分配后必须判断是否成功                                         |          |
| 禁止使用realloc、alloca函数                                       |          |
| 禁止打印文件路径、口令等敏感信息,如有需要,使用private修饰          |          |
| 禁止打印内存地址                                                  |          |
| 整数之间运算时必须严格检查,确保不会出现溢出、反转、除0               |          |
| 禁止对有符号整数进行位操作符运算                                    |          |
| 禁止对指针进行逻辑或位运算                                         |          |
| 循环次数如果收外部数据控制,需要检验其合法性                         |          |
| 禁止使用内存操作类危险函数,需要使用安全函数                         |          |
| 谨慎使用不可重入函数                                               |          |
| 必须检查安全函数的返回值,并进行正确处理                             |          |
| 禁止仅通过TokenType类型判断绕过权限校验                             |          |

**TDD Result**:
![img_v3_0210h_fe78a00d-194a-4907-b999-78fc007ad95g.jpg](https://raw.gitcode.com/user-images/assets/4421702/fe8e5c87-c646-4160-9c73-368316dbef15/img_v3_0210h_fe78a00d-194a-4907-b999-78fc007ad95g.jpg 'img_v3_0210h_fe78a00d-194a-4907-b999-78fc007ad95g.jpg')
**XTS Result**:

### 是否已执行L0用例
- [ ] 已验证
- [ ] 不涉及。如不涉及,请写明理由


See merge request: openharmony/ability_ability_runtime!18713
This commit is contained in:
openharmony_ci
2026-04-09 17:07:42 +08:00
12 changed files with 429 additions and 9 deletions
@@ -62,5 +62,15 @@ bool AbilityLocalRecord::IsHook() const
{
return want_ && want_->GetBoolParam(IS_HOOK, false);
}
void AbilityLocalRecord::SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle)
{
skipAbilityStageLifecycle_ = skipAbilityStageLifecycle;
}
bool AbilityLocalRecord::IsSkipAbilityStageLifecycle() const
{
return skipAbilityStageLifecycle_;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -157,5 +157,15 @@ void AbilityStage::MarkAbilityCreated()
{
isAbilityCreate_ = true;
}
void AbilityStage::SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle)
{
skipAbilityStageLifecycle_ = skipAbilityStageLifecycle;
}
bool AbilityStage::IsSkipAbilityStageLifecycle() const
{
return skipAbilityStageLifecycle_;
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -186,6 +186,7 @@ constexpr const char* INHERIT_PLUGIN_NAMESPACE = "persist.sys.abilityms.inherit_
constexpr const char* PLUGIN_DEFAULT_NAMESPACE_LDDICTIONARY =
"persist.sys.abilityms.plugin_default_namespace_lddictionary";
constexpr char KILL_REASON[] = "Kill Reason:Js Error";
constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle";
const int32_t JSCRASH_TYPE = 3;
const std::string JSVM_TYPE = "ARK";
@@ -825,12 +826,16 @@ void MainThread::ScheduleLaunchAbility(const AbilityInfo &info, const sptr<IRemo
TAG_LOGI(AAFwkTag::APPKIT, "%{public}s called, ability %{public}s, type is %{public}d.",
__func__, info.name.c_str(), info.type);
bool skipAbilityStageLifecycle = false;
if (want != nullptr) {
skipAbilityStageLifecycle = want->GetBoolParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE, false);
want->RemoveParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE);
AAFwk::Want newWant(*want);
newWant.CloseAllFd();
}
std::shared_ptr<AbilityInfo> abilityInfo = std::make_shared<AbilityInfo>(info);
auto abilityRecord = std::make_shared<AbilityLocalRecord>(abilityInfo, token, want, abilityRecordId);
abilityRecord->SetSkipAbilityStageLifecycle(skipAbilityStageLifecycle);
auto tmpWatchdog = watchdog_;
if (tmpWatchdog != nullptr) {
tmpWatchdog->SetBgWorkingThreadStatus(IsBgWorkingThread(info));
@@ -311,7 +311,7 @@ void OHOSApplication::OnConfigurationUpdated(
}
for (auto it = abilityStages_.begin(); it != abilityStages_.end(); it++) {
auto abilityStage = it->second;
if (abilityStage) {
if (abilityStage && !abilityStage->IsSkipAbilityStageLifecycle()) {
abilityStage->OnConfigurationUpdated(config);
}
}
@@ -370,7 +370,7 @@ void OHOSApplication::OnMemoryLevel(int32_t level)
TAG_LOGD(AAFwkTag::APPKIT, "Number of abilityStage to be notified : [%{public}zu]", abilityStages_.size());
for (auto it = abilityStages_.begin(); it != abilityStages_.end(); it++) {
auto abilityStage = it->second;
if (abilityStage) {
if (abilityStage && !abilityStage->IsSkipAbilityStageLifecycle()) {
abilityStage->OnMemoryLevel(level);
}
}
@@ -399,7 +399,7 @@ void OHOSApplication::OnHyperSnapUpdate()
TAG_LOGI(AAFwkTag::APPKIT, "OnHyperSnapUpdate");
AppExecFwk::AppImageObserverManager::GetInstance().NotifyApplicationUpdate();
for (auto& item : abilityStages_) {
if (item.second) {
if (item.second && !item.second->IsSkipAbilityStageLifecycle()) {
item.second->OnLaunchFromHyperSnap();
}
}
@@ -422,8 +422,10 @@ void OHOSApplication::AddAbility(std::shared_ptr<AbilityRuntime::AbilityStage> a
return;
}
if (!abilityStage->IsAbilityCreated()) {
TAG_LOGI(AAFwkTag::APPKIT, "OnAboutToCreateAbility");
abilityStage->OnAboutToCreateAbility();
if (!abilityStage->IsSkipAbilityStageLifecycle()) {
TAG_LOGI(AAFwkTag::APPKIT, "OnAboutToCreateAbility");
abilityStage->OnAboutToCreateAbility();
}
abilityStage->MarkAbilityCreated();
}
abilityStage->AddAbility(token, abilityRecord);
@@ -542,6 +544,7 @@ std::shared_ptr<AbilityRuntime::Context> OHOSApplication::AddAbilityStage(
}
abilityStage->Init(stageContext, weak);
abilityStage->SetSkipAbilityStageLifecycle(abilityRecord->IsSkipAbilityStageLifecycle());
auto firstCallback = CreateFirstStartupCallbackForRecord(abilityStage, abilityRecord, *hapModuleInfo,
callback);
if (firstCallback != nullptr) {
@@ -566,7 +569,9 @@ std::shared_ptr<AbilityRuntime::Context> OHOSApplication::AddAbilityStage(
}
TAG_LOGD(AAFwkTag::APPKIT, "no wait startup second");
abilityStage->OnCreate(want);
if (!abilityStage->IsSkipAbilityStageLifecycle()) {
abilityStage->OnCreate(want);
}
abilityStages_[moduleName] = abilityStage;
} else {
abilityStage = iterator->second;
@@ -886,7 +891,9 @@ void OHOSApplication::CleanAbilityStage(const sptr<IRemoteObject> &token,
}
abilityStage->RemoveAbility(token);
if (!abilityStage->ContainsAbility() && !isCacheProcess) {
abilityStage->OnDestroy();
if (!abilityStage->IsSkipAbilityStageLifecycle()) {
abilityStage->OnDestroy();
}
abilityStages_.erase(moduleName);
}
}
@@ -975,7 +982,7 @@ void OHOSApplication::SchedulePrepareTerminate(const std::string &moduleName,
return;
}
callbackInfo->Push(callback);
if (!iter->second->OnPrepareTerminate(callbackInfo, isAsync)) {
if (iter->second->IsSkipAbilityStageLifecycle() || !iter->second->OnPrepareTerminate(callbackInfo, isAsync)) {
TAG_LOGI(AAFwkTag::APPKIT, "not exist");
AppExecFwk::OnPrepareTerminationResult result = { 0, false };
callbackInfo->Call(result);
@@ -1113,7 +1120,9 @@ void OHOSApplication::CleanEmptyAbilityStage()
continue;
}
if (!abilityStage->ContainsAbility()) {
abilityStage->OnDestroy();
if (!abilityStage->IsSkipAbilityStageLifecycle()) {
abilityStage->OnDestroy();
}
it = abilityStages_.erase(it);
} else {
containsNonEmpty = true;
@@ -76,12 +76,17 @@ public:
const std::shared_ptr<AAFwk::Want> &GetWant();
bool IsHook() const;
void SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle);
bool IsSkipAbilityStageLifecycle() const;
private:
std::shared_ptr<AbilityInfo> abilityInfo_ = nullptr;
sptr<IRemoteObject> token_ = nullptr;
std::shared_ptr<AAFwk::Want> want_ = nullptr;
int32_t abilityRecordId_ = 0;
sptr<AbilityThread> abilityThread_;
bool skipAbilityStageLifecycle_ = false;
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -77,6 +77,9 @@ public:
bool IsAbilityCreated() const;
void MarkAbilityCreated();
void SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle);
bool IsSkipAbilityStageLifecycle() const;
private:
friend class JsAbilityStage;
friend class ETSAbilityStage;
@@ -84,6 +87,7 @@ private:
std::map<sptr<IRemoteObject>, std::shared_ptr<AppExecFwk::AbilityLocalRecord>> abilityRecords_;
std::weak_ptr<AppExecFwk::OHOSApplication> application_;
bool isAbilityCreate_ = false;
bool skipAbilityStageLifecycle_ = false;
};
} // namespace AbilityRuntime
} // namespace OHOS
@@ -48,6 +48,7 @@ struct StartAbilityInfo {
int32_t status = ERR_OK;
AppExecFwk::ExtensionProcessMode extensionProcessMode = AppExecFwk::ExtensionProcessMode::UNDEFINED;
bool isTargetPlugin = false;
bool skipAbilityStageLifecycle = false;
};
struct StartAbilityUtils {
@@ -360,6 +360,7 @@ constexpr uint32_t TARGET_TYPE_INIT = 100;
constexpr int64_t USER_SWITCH_TIMEOUT = 3 * 1000; // 3s
constexpr const char* SUPPORT_LINKAGE_SCENE = "const.window.supportLinkageScene";
constexpr const char* KEY_SPECIFIED_FLAG = "com.ohos.param.specifiedFlag";
constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle";
const bool REGISTER_RESULT =
SystemAbility::MakeAndRegisterAbility(DelayedSingleton<AbilityManagerService>::GetInstance().get());
@@ -8293,6 +8294,12 @@ int AbilityManagerService::GenerateAbilityRequest(const Want &want, int requestC
request.collaboratorType = GetCollaboratorType(request.abilityInfo.applicationInfo.codePath);
request.isTargetPlugin = abilityInfo->isTargetPlugin;
if (request.abilityInfo.extensionAbilityType == AppExecFwk::ExtensionAbilityType::BACKUP &&
!request.abilityInfo.applicationInfo.allowMultiProcess) {
request.want.SetParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE, abilityInfo->skipAbilityStageLifecycle);
TAG_LOGD(AAFwkTag::ABILITYMGR, "set skipAbilityStageLifecycle for backup extension");
}
if (request.abilityInfo.type == AppExecFwk::AbilityType::SERVICE && request.abilityInfo.isStageBasedModel) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "stage mode, abilityInfo SERVICE type reset EXTENSION");
request.abilityInfo.type = AppExecFwk::AbilityType::EXTENSION;
@@ -300,6 +300,7 @@ std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartAbilityInfo(const
return request;
}
request->extensionProcessMode = extensionInfo.extensionProcessMode;
request->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle;
// For compatibility translates to AbilityInfo
AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, request->abilityInfo);
}
@@ -374,6 +375,7 @@ void StartAbilityInfo::FindExtensionInfo(const Want &want, int32_t flags, int32_
return;
}
abilityInfo->customProcess = extensionInfo.customProcess;
abilityInfo->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle;
TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionInfo customProcess: %{public}s", abilityInfo->customProcess.c_str());
if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) {
abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode;
@@ -30,6 +30,7 @@ namespace AppExecFwk {
namespace {
constexpr const char* REUSING_WINDOW = "ohos.ability_runtime.reusing_window";
constexpr const char* IS_HOOK = "ohos.ability_runtime.is_hook";
constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle";
}
AppLifeCycleDeal::AppLifeCycleDeal()
{}
@@ -111,6 +112,7 @@ void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord>
if (ability->GetWant() != nullptr) {
ability->GetWant()->RemoveParam(REUSING_WINDOW);
ability->GetWant()->RemoveParam(IS_HOOK);
ability->GetWant()->RemoveParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE);
}
} else {
TAG_LOGW(AAFwkTag::APPMGR, "null appThread or ability");
@@ -27,8 +27,11 @@ public:
MockAbilityStage() {}
~MockAbilityStage() {}
MOCK_CONST_METHOD0(OnDestroy, void());
MOCK_METHOD1(OnMemoryLevel, void(int));
MOCK_METHOD5(RunAutoStartupTask, int32_t(const std::function<void()>&, std::shared_ptr<AAFwk::Want>, bool&,
const std::shared_ptr<Context>&, bool));
MOCK_METHOD0(OnAboutToCreateAbility, void());
MOCK_METHOD0(OnLaunchFromHyperSnap, void());
};
} // namespace AbilityRuntime
@@ -44,6 +44,35 @@ using namespace testing::ext;
namespace OHOS {
namespace AppExecFwk {
namespace {
class PrepareTerminateCountStage : public AbilityRuntime::AbilityStage {
public:
explicit PrepareTerminateCountStage(bool returnValue) : returnValue_(returnValue) {}
bool OnPrepareTerminate(
AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnPrepareTerminationResult> *,
bool &isAsync) const override
{
callCount_++;
isAsync = false;
return returnValue_;
}
mutable int32_t callCount_ = 0;
bool returnValue_ = false;
};
class ConfigUpdateCountStage : public AbilityRuntime::AbilityStage {
public:
void OnConfigurationUpdated(const AppExecFwk::Configuration &) override
{
++updateCount_;
}
int32_t updateCount_ = 0;
};
}
class OHOSApplicationTest : public testing::Test {
public:
static void SetUpTestCase();
@@ -399,6 +428,78 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpda
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0300 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310
* @tc.name: OnConfigurationUpdated
* @tc.desc: Verify calls abilityStage OnConfigurationUpdated when skipAbilityStageLifecycle is false
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310 start.";
std::string bundleName = "test.bundleName";
std::string moduleName = "test.moduleName";
std::string hapPath = "/data/app/testHap";
std::vector<std::string> overlayPaths;
std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
ASSERT_NE(resConfig, nullptr);
std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager(
bundleName, moduleName, hapPath, overlayPaths, *resConfig));
ASSERT_NE(resourceManager, nullptr);
auto contextImpl = std::make_shared<AbilityRuntime::ContextImpl>();
contextImpl->SetResourceManager(resourceManager);
auto appContext = std::make_shared<AbilityRuntime::ApplicationContext>();
appContext->AttachContextImpl(contextImpl);
ohosApplication_->SetApplicationContext(appContext);
ohosApplication_->abilityRecordMgr_ = std::make_shared<AbilityRecordMgr>();
ohosApplication_->configuration_ = std::make_shared<Configuration>();
auto stage = std::make_shared<ConfigUpdateCountStage>();
stage->SetSkipAbilityStageLifecycle(false);
ohosApplication_->abilityStages_.emplace("entry_config_false", stage);
Configuration config;
config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "zh");
ohosApplication_->OnConfigurationUpdated(config);
EXPECT_EQ(stage->updateCount_, 1);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320
* @tc.name: OnConfigurationUpdated
* @tc.desc: Verify does not call abilityStage OnConfigurationUpdated when skipAbilityStageLifecycle is true
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320 start.";
std::string bundleName = "test.bundleName";
std::string moduleName = "test.moduleName";
std::string hapPath = "/data/app/testHap";
std::vector<std::string> overlayPaths;
std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
ASSERT_NE(resConfig, nullptr);
std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager(
bundleName, moduleName, hapPath, overlayPaths, *resConfig));
ASSERT_NE(resourceManager, nullptr);
auto contextImpl = std::make_shared<AbilityRuntime::ContextImpl>();
contextImpl->SetResourceManager(resourceManager);
auto appContext = std::make_shared<AbilityRuntime::ApplicationContext>();
appContext->AttachContextImpl(contextImpl);
ohosApplication_->SetApplicationContext(appContext);
ohosApplication_->abilityRecordMgr_ = std::make_shared<AbilityRecordMgr>();
ohosApplication_->configuration_ = std::make_shared<Configuration>();
auto stage = std::make_shared<ConfigUpdateCountStage>();
stage->SetSkipAbilityStageLifecycle(true);
ohosApplication_->abilityStages_.emplace("entry_config_true", stage);
Configuration config;
config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "zh");
ohosApplication_->OnConfigurationUpdated(config);
EXPECT_EQ(stage->updateCount_, 0);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320 end.";
}
/*
* @tc.number: OnConfigurationUpdated_0600
* @tc.name: OnConfigurationUpdated
@@ -481,6 +582,44 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0200,
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0200 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210
* @tc.name: OnMemoryLevel
* @tc.desc: Verify calls abilityStage OnMemoryLevel when skipAbilityStageLifecycle is false
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210 start.";
constexpr int32_t level = 1;
ohosApplication_->abilityRuntimeContext_ = std::make_shared<AbilityRuntime::ApplicationContext>();
auto mockAbilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
mockAbilityStage->SetSkipAbilityStageLifecycle(false);
ohosApplication_->abilityStages_.emplace("entry_memory_false", mockAbilityStage);
EXPECT_CALL(*mockAbilityStage, OnMemoryLevel(level)).Times(1);
ohosApplication_->OnMemoryLevel(level);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220
* @tc.name: OnMemoryLevel
* @tc.desc: Verify does not call abilityStage OnMemoryLevel when skipAbilityStageLifecycle is true
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220 start.";
constexpr int32_t level = 1;
ohosApplication_->abilityRuntimeContext_ = std::make_shared<AbilityRuntime::ApplicationContext>();
auto mockAbilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
mockAbilityStage->SetSkipAbilityStageLifecycle(true);
ohosApplication_->abilityStages_.emplace("entry_memory_true", mockAbilityStage);
EXPECT_CALL(*mockAbilityStage, OnMemoryLevel(level)).Times(0);
ohosApplication_->OnMemoryLevel(level);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0100
* @tc.name: AddAbilityStage
@@ -616,6 +755,58 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_070
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0700 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710
* @tc.name: AddAbilityStage
* @tc.desc: Verify function AddAbilityStage skipAbilityStageLifecycle false branch
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710 start.";
sptr<Notification::MockIRemoteObject> token = new (std::nothrow) Notification::MockIRemoteObject();
std::shared_ptr<AbilityInfo> info = std::make_shared<AbilityInfo>();
info->moduleName = "entry_skip_false";
auto abilityRecord = std::make_shared<AbilityLocalRecord>(info, token, nullptr, 0);
abilityRecord->SetSkipAbilityStageLifecycle(false);
auto callback = [](const std::shared_ptr<AbilityRuntime::Context> &) {};
bool isAsyncCallback = false;
auto context = ohosApplication_->AddAbilityStage(abilityRecord, callback, isAsyncCallback);
EXPECT_NE(context, nullptr);
auto it = ohosApplication_->abilityStages_.find(info->moduleName);
ASSERT_NE(it, ohosApplication_->abilityStages_.end());
ASSERT_NE(it->second, nullptr);
EXPECT_FALSE(it->second->IsSkipAbilityStageLifecycle());
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720
* @tc.name: AddAbilityStage
* @tc.desc: Verify function AddAbilityStage skipAbilityStageLifecycle true branch
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720 start.";
sptr<Notification::MockIRemoteObject> token = new (std::nothrow) Notification::MockIRemoteObject();
std::shared_ptr<AbilityInfo> info = std::make_shared<AbilityInfo>();
info->moduleName = "entry_skip_true";
auto abilityRecord = std::make_shared<AbilityLocalRecord>(info, token, nullptr, 0);
abilityRecord->SetSkipAbilityStageLifecycle(true);
auto callback = [](const std::shared_ptr<AbilityRuntime::Context> &) {};
bool isAsyncCallback = false;
auto context = ohosApplication_->AddAbilityStage(abilityRecord, callback, isAsyncCallback);
EXPECT_NE(context, nullptr);
auto it = ohosApplication_->abilityStages_.find(info->moduleName);
ASSERT_NE(it, ohosApplication_->abilityStages_.end());
ASSERT_NE(it->second, nullptr);
EXPECT_TRUE(it->second->IsSkipAbilityStageLifecycle());
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0800
* @tc.name: AddAbilityStage
@@ -775,6 +966,56 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0300 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400
* @tc.name: CleanAbilityStage
* @tc.desc: Verify function CleanAbilityStage calls OnDestroy when skipAbilityStageLifecycle is false
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400 start.";
std::string moduleName = "entry_clean_destroy_false";
std::shared_ptr<AbilityInfo> abilityInfo = std::make_shared<AbilityInfo>();
abilityInfo->moduleName = moduleName;
sptr<Notification::MockIRemoteObject> token = new (std::nothrow) Notification::MockIRemoteObject();
auto abilityRecord = std::make_shared<AbilityLocalRecord>(abilityInfo, token, nullptr, 0);
auto mockAbilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
mockAbilityStage->SetSkipAbilityStageLifecycle(false);
mockAbilityStage->AddAbility(token, abilityRecord);
ohosApplication_->abilityStages_.emplace(moduleName, mockAbilityStage);
EXPECT_CALL(*mockAbilityStage, OnDestroy()).Times(1);
ohosApplication_->CleanAbilityStage(token, abilityInfo, false);
EXPECT_EQ(ohosApplication_->abilityStages_.find(moduleName), ohosApplication_->abilityStages_.end());
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500
* @tc.name: CleanAbilityStage
* @tc.desc: Verify function CleanAbilityStage does not call OnDestroy when skipAbilityStageLifecycle is true
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500 start.";
std::string moduleName = "entry_clean_destroy_true";
std::shared_ptr<AbilityInfo> abilityInfo = std::make_shared<AbilityInfo>();
abilityInfo->moduleName = moduleName;
sptr<Notification::MockIRemoteObject> token = new (std::nothrow) Notification::MockIRemoteObject();
auto abilityRecord = std::make_shared<AbilityLocalRecord>(abilityInfo, token, nullptr, 0);
auto mockAbilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
mockAbilityStage->SetSkipAbilityStageLifecycle(true);
mockAbilityStage->AddAbility(token, abilityRecord);
ohosApplication_->abilityStages_.emplace(moduleName, mockAbilityStage);
EXPECT_CALL(*mockAbilityStage, OnDestroy()).Times(0);
ohosApplication_->CleanAbilityStage(token, abilityInfo, false);
EXPECT_EQ(ohosApplication_->abilityStages_.find(moduleName), ohosApplication_->abilityStages_.end());
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_GetAppContext_0100
* @tc.name: GetAppContext
@@ -838,6 +1079,82 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_ScheduleAcceptWant_
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_ScheduleAcceptWant_0100 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100
* @tc.name: SchedulePrepareTerminate
* @tc.desc: Verify does not call OnPrepareTerminate when skipAbilityStageLifecycle is true
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100 start.";
bool isAsync = true;
bool callbackCalled = false;
auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) {
callbackCalled = true;
};
std::string moduleName = "entry_prepare_skip_true";
auto abilityStage = std::make_shared<PrepareTerminateCountStage>(true);
abilityStage->SetSkipAbilityStageLifecycle(true);
ohosApplication_->abilityStages_.emplace(moduleName, abilityStage);
ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync);
EXPECT_EQ(abilityStage->callCount_, 0);
EXPECT_TRUE(callbackCalled);
EXPECT_FALSE(isAsync);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200
* @tc.name: SchedulePrepareTerminate
* @tc.desc: Verify calls fallback callback when OnPrepareTerminate returns false
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200 start.";
bool isAsync = false;
bool callbackCalled = false;
auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) {
callbackCalled = true;
};
std::string moduleName = "entry_prepare_return_false";
auto abilityStage = std::make_shared<PrepareTerminateCountStage>(false);
abilityStage->SetSkipAbilityStageLifecycle(false);
ohosApplication_->abilityStages_.emplace(moduleName, abilityStage);
ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync);
EXPECT_EQ(abilityStage->callCount_, 1);
EXPECT_TRUE(callbackCalled);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300
* @tc.name: SchedulePrepareTerminate
* @tc.desc: Verify does not call fallback callback when OnPrepareTerminate returns true
*/
HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300 start.";
bool isAsync = false;
bool callbackCalled = false;
auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) {
callbackCalled = true;
};
std::string moduleName = "entry_prepare_return_true";
auto abilityStage = std::make_shared<PrepareTerminateCountStage>(true);
abilityStage->SetSkipAbilityStageLifecycle(false);
ohosApplication_->abilityStages_.emplace(moduleName, abilityStage);
ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync);
EXPECT_EQ(abilityStage->callCount_, 1);
EXPECT_FALSE(callbackCalled);
GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300 end.";
}
/*
* @tc.number: AppExecFwk_OHOSApplicationTest_GetConfiguration_0100
* @tc.name: GetConfiguration
@@ -1625,6 +1942,26 @@ HWTEST_F(OHOSApplicationTest, OnUpdate_0100, TestSize.Level1)
GTEST_LOG_(INFO) << "OnUpdate_0100 end.";
}
/*
* @tc.number: OnUpdate_0200
* @tc.name: OnUpdate
* @tc.desc: Verify skipAbilityStageLifecycle=true does not call OnLaunchFromHyperSnap
*/
HWTEST_F(OHOSApplicationTest, OnUpdate_0200, TestSize.Level1)
{
GTEST_LOG_(INFO) << "OnUpdate_0200 start.";
auto ohosApplication = std::make_shared<OHOSApplication>();
ASSERT_NE(ohosApplication, nullptr);
auto abilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
ASSERT_NE(abilityStage, nullptr);
abilityStage->SetSkipAbilityStageLifecycle(true);
ohosApplication->abilityStages_["test_skip_true"] = abilityStage;
EXPECT_CALL(*abilityStage, OnLaunchFromHyperSnap()).Times(0);
ohosApplication->OnHyperSnapUpdate();
GTEST_LOG_(INFO) << "OnUpdate_0200 end.";
}
/*
* @tc.number: AddAbility_ShouldDonothingWhenInputIsInvalid
* @tc.name: AddAbility
@@ -1678,6 +2015,31 @@ HWTEST_F(OHOSApplicationTest, AddAbility_ShouldAddAbilityToAbilityStageWhenInput
GTEST_LOG_(INFO) << "AddAbility_ShouldAddAbilityToAbilityStageWhenInputIsValid end.";
}
/*
* @tc.number: AddAbility_0100
* @tc.name: AddAbility
* @tc.desc: Verify OnAboutToCreateAbility is not called when skipAbilityStageLifecycle is true
*/
HWTEST_F(OHOSApplicationTest, AddAbility_0200, TestSize.Level1)
{
GTEST_LOG_(INFO) << "AddAbility_0200 start.";
auto ohosApplication = std::make_shared<OHOSApplication>();
ASSERT_NE(ohosApplication, nullptr);
auto abilityStage = std::make_shared<AbilityRuntime::MockAbilityStage>();
ASSERT_NE(abilityStage, nullptr);
abilityStage->SetSkipAbilityStageLifecycle(true);
sptr<Notification::MockIRemoteObject> token = new (std::nothrow) Notification::MockIRemoteObject();
ASSERT_NE(token, nullptr);
auto abilityRecord = std::make_shared<AbilityLocalRecord>(nullptr, token, nullptr, 0);
ASSERT_NE(abilityRecord, nullptr);
EXPECT_CALL(*abilityStage, OnAboutToCreateAbility()).Times(0);
ohosApplication->AddAbility(abilityStage, token, abilityRecord);
EXPECT_TRUE(abilityStage->ContainsAbility());
GTEST_LOG_(INFO) << "AddAbility_0200 end.";
}
/**
* @tc.number: AppExecFwk_OHOSApplicationTest_LaunchElement_0100
* @tc.name: AddAbilityStage sets launchElement with valid Want