1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <gtest/gtest.h>
16#include "gmock/gmock.h"
17
18#include <thread>
19#include <chrono>
20
21#define private public
22#define protected public
23#include "lifecycle_test_base.h"
24#undef private
25#undef protected
26
27using namespace testing;
28using namespace testing::ext;
29using namespace OHOS::AppExecFwk;
30
31namespace OHOS {
32namespace AAFwk {
33#ifdef SUPPORT_ASAN
34constexpr uint32_t LOAD_TIMEOUT = 150000;            // ms
35constexpr uint32_t ACTIVE_TIMEOUT = 75000;          // ms
36constexpr uint32_t INACTIVE_TIMEOUT = 7500;         // ms
37#else
38constexpr uint32_t LOAD_TIMEOUT = 10000;            // ms
39constexpr uint32_t ACTIVE_TIMEOUT = 5000;          // ms
40constexpr uint32_t INACTIVE_TIMEOUT = 500;         // ms
41#endif
42class LifecycleTest : public testing::Test, public LifecycleTestBase {
43public:
44    static void SetUpTestCase();
45
46    static void TearDownTestCase();
47
48    void SetUp();
49
50    void TearDown();
51
52    bool StartNextAbility() override;
53
54    int AttachAbility(const OHOS::sptr<OHOS::AAFwk::AbilityScheduler>& scheduler,
55        const OHOS::sptr<OHOS::IRemoteObject>& token) override;
56
57    void OnStartabilityAms();
58public:
59    int startLancherFlag_ = false;
60
61    std::shared_ptr<OHOS::AAFwk::AbilityRecord> launcherAbilityRecord_{ nullptr };  // launcher ability
62    OHOS::sptr<OHOS::IRemoteObject> launcherToken_{ nullptr };                      // token of launcher ability
63    std::shared_ptr<OHOS::AAFwk::AbilityRecord> nextAbilityRecord_{ nullptr };      // ability being launched
64    OHOS::sptr<OHOS::IRemoteObject> nextToken_{ nullptr };                          // token of ability being launched
65    OHOS::sptr<OHOS::AAFwk::AbilityScheduler> launcherScheduler_{ nullptr };        // launcher ability thread interface
66    OHOS::sptr<OHOS::AAFwk::AbilityScheduler> nextScheduler_{ nullptr };            // next ability thread interface
67    std::unique_ptr<LifeTestCommand> command_{ nullptr };                           // test command_ interact with ams_
68};
69
70void LifecycleTest::SetUpTestCase() {}
71
72void LifecycleTest::TearDownTestCase()
73{
74    OHOS::DelayedSingleton<SaMgrClient>::DestroyInstance();
75}
76
77void LifecycleTest::SetUp() {}
78
79void LifecycleTest::TearDown() {}
80
81bool LifecycleTest::StartNextAbility()
82{
83    return true;
84}
85
86int LifecycleTest::AttachAbility(
87    const OHOS::sptr<OHOS::AAFwk::AbilityScheduler>& scheduler, const OHOS::sptr<OHOS::IRemoteObject>& token)
88{
89    auto abilityMs_ = std::make_shared<AbilityManagerService>();
90    return abilityMs_->AttachAbilityThread(scheduler, token);
91}
92
93/*
94 * Feature: Lifecycle schedule
95 * Function: Lifecycle schedule
96 * SubFunction: NA
97 * FunctionPoints: AttachAbilityThread
98 * EnvConditions:NA
99 * CaseDescription: verify AttachAbilityThread parameters.
100 * AttachAbilityThread fail if IAbilityScheduler or token is nullptr.
101 */
102HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_001, TestSize.Level1)
103{
104    auto abilityMs_ = std::make_shared<AbilityManagerService>();
105    if (startLancherFlag_) {
106        EXPECT_TRUE(abilityMs_);
107        EXPECT_TRUE(launcherAbilityRecord_);
108        EXPECT_NE(abilityMs_->AttachAbilityThread(nullptr, launcherToken_), 0);
109        EXPECT_NE(abilityMs_->AttachAbilityThread(launcherScheduler_, nullptr), 0);
110        EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::ACTIVE);
111    }
112}
113
114/*
115 * Feature: Lifecycle schedule
116 * Function: Lifecycle schedule
117 * SubFunction: NA
118 * FunctionPoints: AttachAbilityThread
119 * EnvConditions:NA
120 * CaseDescription: verify launcher AbilityRecord state_ when AttachAbilityThread success.
121 * 1. AbilityState transferred from INITIAL to ACTIVATING.
122 * 2. AbilityRecord is attached.
123 */
124HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_002, TestSize.Level1)
125{
126    auto abilityMs_ = std::make_shared<AbilityManagerService>();
127    if (startLancherFlag_) {
128        EXPECT_TRUE(abilityMs_);
129        EXPECT_TRUE(launcherAbilityRecord_);
130        EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::ACTIVE);
131        EXPECT_TRUE(launcherScheduler_);
132        EXPECT_TRUE(launcherToken_);
133        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
134        EXPECT_EQ(launcherAbilityRecord_->IsReady(), true);
135    }
136}
137
138/*
139 * Feature: Lifecycle schedule
140 * Function: Lifecycle schedule
141 * SubFunction: NA
142 * FunctionPoints: AttachAbilityThread
143 * EnvConditions:NA
144 * CaseDescription: verify AbilityRecord transition timeout handler.
145 */
146HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_003, TestSize.Level1)
147{
148    auto abilityMs_ = std::make_shared<AbilityManagerService>();
149    if (startLancherFlag_) {
150        command_->callback_ = false;
151        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
152        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
153        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
154        pthread_t tid = 0;
155        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
156        int ret =
157            LifecycleTest::SemTimedWaitMillis(LOAD_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
158        EXPECT_NE(ret, 0);
159        // check timeout handler
160        EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::ACTIVE);
161        pthread_join(tid, nullptr);
162    }
163}
164
165/*
166 * Feature: Lifecycle schedule
167 * Function: Lifecycle schedule
168 * SubFunction: NA
169 * FunctionPoints: AttachAbilityThread
170 * EnvConditions:NA
171 * CaseDescription: verify AbilityTransitionDone parameters.
172 * AbilityTransitionDone fail if launcher schedules incorrect Life state_.
173 */
174HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_004, TestSize.Level1)
175{
176    auto abilityMs_ = std::make_shared<AbilityManagerService>();
177    if (startLancherFlag_) {
178        // AttachAbilityThread done and success
179        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
180
181        command_->callback_ = true;
182        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
183        command_->abnormalState_ = OHOS::AAFwk::AbilityState::INACTIVE;
184        pthread_t tid = 0;
185        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
186        int ret =
187            LifecycleTest::SemTimedWaitMillis(LOAD_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
188        if (ret != 0) {
189            // check timeout handler
190            GTEST_LOG_(INFO) << "timeout. It shouldn't happen.";
191            pthread_join(tid, nullptr);
192            return;
193        }
194        pthread_join(tid, nullptr);
195    }
196}
197
198/*
199 * Feature: Lifecycle schedule
200 * Function: Lifecycle schedule
201 * SubFunction: NA
202 * FunctionPoints: AttachAbilityThread
203 * EnvConditions:NA
204 * CaseDescription: AttachAbilityThread done, verify AbilityRecord state_ when AbilityStartThread success.
205 * 1. Life transition from UNDEFINED to ACTIVATING to ACTIVE.
206 * 2. AbilityRecord is attached.
207 */
208HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_005, TestSize.Level1)
209{
210    auto abilityMs_ = std::make_shared<AbilityManagerService>();
211    if (startLancherFlag_) {
212        // AttachAbilityThread done and success
213        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
214        command_->callback_ = true;
215        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
216        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
217        pthread_t tid = 0;
218
219        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
220        int ret =
221            LifecycleTest::SemTimedWaitMillis(LOAD_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
222        if (ret != 0) {
223            // check timeout handler. It won't happen normally.
224            GTEST_LOG_(INFO) << "timeout. It shouldn't happen.";
225            pthread_join(tid, nullptr);
226            return;
227        }
228        PacMap saveData;
229        abilityMs_->AbilityTransitionDone(launcherToken_, command_->state_, saveData);
230        if (launcherAbilityRecord_->GetAbilityState() != OHOS::AAFwk::AbilityState::ACTIVE) {
231            EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::ACTIVE);
232        }
233        EXPECT_EQ(launcherAbilityRecord_->IsReady(), true);
234        pthread_join(tid, nullptr);
235    }
236}
237
238/*
239 * Feature: Lifecycle schedule
240 * Function: Lifecycle schedule
241 * SubFunction: NA
242 * FunctionPoints: AttachAbilityThread
243 * EnvConditions:NA
244 * CaseDescription:  hnadeler is timeout
245 */
246HWTEST_F(LifecycleTest, AAFWK_AbilityMS_StartLauncherAbilityLifeCycle_006, TestSize.Level1)
247{
248    auto abilityMs_ = std::make_shared<AbilityManagerService>();
249    if (startLancherFlag_) {
250        command_->callback_ = false;
251        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
252        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
253        pthread_t tid = 0;
254        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
255        int ret = LifecycleTest::SemTimedWaitMillis(ACTIVE_TIMEOUT, command_->sem_);
256        EXPECT_NE(ret, 0);
257        // check AttachAbilityThread timeout handler
258        EXPECT_EQ(launcherAbilityRecord_->IsReady(), false);
259        pthread_join(tid, nullptr);
260    }
261}
262
263/*
264 * Feature: Lifecycle schedule
265 * Function: Lifecycle schedule
266 * SubFunction: NA
267 * FunctionPoints: AbilityTransitionDone
268 * EnvConditions:NA
269 * CaseDescription: launcher OnInactive timeout, verify launcher AbilityTransitionDone timeout handler.
270 */
271HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_001, TestSize.Level1)
272{
273    auto abilityMs_ = std::make_shared<AbilityManagerService>();
274    if (startLancherFlag_) {
275        command_->callback_ = false;
276        command_->expectState_ = OHOS::AAFwk::AbilityState::INACTIVE;
277        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
278        // launcher is in inactivating process.
279        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
280        EXPECT_TRUE(StartNextAbility());
281        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
282        pthread_t tid = 0;
283        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
284        int ret = LifecycleTest::SemTimedWaitMillis(INACTIVE_TIMEOUT, command_->sem_);
285        EXPECT_NE(ret, 0);
286        // check AbilityTransitionDone timeout handler
287        EXPECT_NE(nextAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::INACTIVATING);
288        pthread_join(tid, nullptr);
289    }
290}
291
292/*
293 * Feature: Lifecycle schedule
294 * Function: Lifecycle schedule
295 * SubFunction: NA
296 * FunctionPoints: AbilityTransitionDone
297 * EnvConditions:NA
298 * CaseDescription: verify AbilityTransitionDone parameters.
299 * AbilityTransitionDone fail if life state_ is incompatible with
300 * OnInactive process. Or launcher schedules incorrect life state_.
301 */
302HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_002, TestSize.Level1)
303{
304    auto abilityMs_ = std::make_shared<AbilityManagerService>();
305    if (startLancherFlag_) {
306        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
307        EXPECT_TRUE(StartNextAbility());
308        // launcher is in inactivating process.
309        PacMap saveData;
310        EXPECT_NE(abilityMs_->AbilityTransitionDone(launcherToken_, OHOS::AAFwk::AbilityState::ACTIVE, saveData), 0);
311        EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::INACTIVATING);
312        EXPECT_EQ(nextAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::INITIAL);
313    }
314}
315
316/*
317 * Feature: Lifecycle schedule
318 * Function: Lifecycle schedule
319 * SubFunction: NA
320 * FunctionPoints: AttachAbilityThread
321 * EnvConditions:NA
322 * CaseDescription: launcher OnInactive done, verify new ability AttachAbilityThread timeout handler.
323 */
324HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_003, TestSize.Level1)
325{
326    auto abilityMs_ = std::make_shared<AbilityManagerService>();
327    if (startLancherFlag_) {
328        command_->callback_ = false;
329        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
330        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
331        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
332        EXPECT_TRUE(StartNextAbility());
333        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
334        PacMap saveData;
335        EXPECT_EQ(abilityMs_->AbilityTransitionDone(launcherToken_, OHOS::AAFwk::AbilityState::INACTIVE, saveData), 0);
336        // launcher oninactive done.
337        pthread_t tid = 0;
338        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
339        int ret = LifecycleTest::SemTimedWaitMillis(
340            INACTIVE_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
341        EXPECT_NE(ret, 0);
342        // check timeout handler
343        EXPECT_EQ(nextAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::ACTIVATING);
344        pthread_join(tid, nullptr);
345    }
346}
347
348/*
349 * Feature: Lifecycle schedule
350 * Function: Lifecycle schedule
351 * SubFunction: NA
352 * FunctionPoints: AbilityTransitionDone
353 * EnvConditions:NA
354 * CaseDescription: launcher OnInactive done, verify AbilityTransitionDone parameter.
355 * AbilityTransitionDone fail if new ability
356 * IAbilityScheduler is nullptr.
357 */
358HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_004, TestSize.Level1)
359{
360    auto abilityMs_ = std::make_shared<AbilityManagerService>();
361    if (startLancherFlag_) {
362        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
363        EXPECT_TRUE(StartNextAbility());
364        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
365        PacMap saveData;
366        EXPECT_EQ(abilityMs_->AbilityTransitionDone(launcherToken_, OHOS::AAFwk::AbilityState::INACTIVE, saveData), 0);
367        // launcher oninactive done.
368        nextAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INITIAL);
369        EXPECT_EQ(AttachAbility(nextScheduler_, nextToken_), 0);
370        EXPECT_NE(abilityMs_->AbilityTransitionDone(nullptr, OHOS::AAFwk::AbilityState::ACTIVE, saveData), 0);
371    }
372}
373
374/*
375 * Feature: Lifecycle schedule
376 * Function: Lifecycle schedule
377 * SubFunction: NA
378 * FunctionPoints: AbilityTransitionDone
379 * EnvConditions:NA
380 * CaseDescription: launcher OnInactive done. verify AbilityTransitionDone parameter.
381 * AbilityTransitionDone fail if new ability
382 * schedules incorrect state_.
383 */
384HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_005, TestSize.Level1)
385{
386    auto abilityMs_ = std::make_shared<AbilityManagerService>();
387    if (startLancherFlag_) {
388        command_->callback_ = true;
389        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
390        command_->abnormalState_ = OHOS::AAFwk::AbilityState::INACTIVE;
391        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
392        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
393        EXPECT_TRUE(StartNextAbility());
394        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
395        PacMap saveData;
396        EXPECT_EQ(abilityMs_->AbilityTransitionDone(launcherToken_, OHOS::AAFwk::AbilityState::INACTIVE, saveData), 0);
397        // launcher oninactive done.
398        nextAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INITIAL);
399        EXPECT_EQ(AttachAbility(nextScheduler_, nextToken_), 0);
400        pthread_t tid = 0;
401        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
402        int ret =
403            LifecycleTest::SemTimedWaitMillis(LOAD_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
404        if (ret != 0) {
405            // check timeout handler
406            pthread_join(tid, nullptr);
407            return;
408        }
409        pthread_join(tid, nullptr);
410    }
411}
412
413/*
414 * Feature: Lifecycle schedule
415 * Function: Lifecycle schedule
416 * SubFunction: NA
417 * FunctionPoints: AbilityTransitionDone
418 * EnvConditions:NA
419 * CaseDescription: launcher OnInactive done. verify new ability AbilityTransitionDone timeout handler.
420 */
421HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_006, TestSize.Level1)
422{
423    auto abilityMs_ = std::make_shared<AbilityManagerService>();
424    if (startLancherFlag_) {
425        command_->callback_ = false;
426        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
427        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
428        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
429        EXPECT_TRUE(StartNextAbility());
430        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
431        // launcher oninactive done.
432        EXPECT_EQ(AttachAbility(nextScheduler_, nextToken_), 0);
433        pthread_t tid = 0;
434        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
435        int ret =
436            LifecycleTest::SemTimedWaitMillis(ACTIVE_TIMEOUT + DELAY_TEST_TIME, command_->sem_);
437        EXPECT_NE(ret, 0);
438        pthread_join(tid, nullptr);
439        return;
440    }
441}
442
443/*
444 * Feature: Lifecycle schedule
445 * Function: Lifecycle schedule
446 * SubFunction: NA
447 * FunctionPoints: AttachAbilityThread AbilityTransitionDone
448 * EnvConditions:NA
449 * CaseDescription: launcher OnInactive done and starts new ability success. verify new AbilityRecord.
450 * 1. Launcher oninactive done and is INACTIVE.
451 * 2. new ability is ACTIVE.
452 */
453HWTEST_F(LifecycleTest, AAFWK_AbilityMS_startAbilityLifeCycle_007, TestSize.Level1)
454{
455    auto abilityMs_ = std::make_shared<AbilityManagerService>();
456    if (startLancherFlag_) {
457        command_->callback_ = true;
458        command_->expectState_ = OHOS::AAFwk::AbilityState::ACTIVE;
459        command_->state_ = OHOS::AAFwk::AbilityState::INITIAL;
460        EXPECT_EQ(AttachAbility(launcherScheduler_, launcherToken_), 0);
461        EXPECT_TRUE(StartNextAbility());
462        launcherAbilityRecord_->SetAbilityState(OHOS::AAFwk::AbilityState::INACTIVATING);
463        PacMap saveData;
464        EXPECT_EQ(abilityMs_->AbilityTransitionDone(
465            launcherToken_, OHOS::AAFwk::AbilityState::INACTIVE, saveData), OHOS::ERR_OK);
466        // launcher oninactive done.
467        EXPECT_EQ(launcherAbilityRecord_->GetAbilityState(), OHOS::AAFwk::AbilityState::INACTIVE);
468        EXPECT_EQ(AttachAbility(nextScheduler_, nextToken_), 0);
469        pthread_t tid = 0;
470        pthread_create(&tid, nullptr, LifecycleTest::AbilityStartThread, command_.get());
471        int ret = LifecycleTest::SemTimedWaitMillis(ACTIVE_TIMEOUT * 2, command_->sem_);
472        if (ret != 0) {
473            // check timeout handler
474            pthread_join(tid, nullptr);
475            return;
476        }
477        pthread_join(tid, nullptr);
478    }
479}
480}  // namespace AAFwk
481}  // namespace OHOS
482