1/*
2 * Copyright (c) 2021-2024 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
16#include "user_controller.h"
17
18#include "ability_manager_service.h"
19#include "hilog_tag_wrapper.h"
20#include "mock_session_manager_service.h"
21#include "os_account_manager_wrapper.h"
22#include "scene_board_judgement.h"
23
24namespace OHOS {
25namespace AAFwk {
26using namespace OHOS::AppExecFwk;
27namespace {
28const int64_t USER_SWITCH_TIMEOUT = 3 * 1000; // 3s
29}
30
31UserItem::UserItem(int32_t id) : userId_(id)
32{}
33
34UserItem::~UserItem() {}
35
36int32_t UserItem::GetUserId()
37{
38    return userId_;
39}
40
41void UserItem::SetState(const UserState &state)
42{
43    if (curState_ == state) {
44        return;
45    }
46    lastState_ = curState_;
47    curState_ = state;
48}
49
50UserState UserItem::GetState()
51{
52    return curState_;
53}
54
55UserController::UserController()
56{
57}
58
59UserController::~UserController()
60{
61}
62
63void UserController::Init()
64{
65    auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
66    if (!handler) {
67        return;
68    }
69
70    if (eventHandler_) {
71        return;
72    }
73    eventHandler_ = std::make_shared<UserEventHandler>(handler, shared_from_this());
74}
75
76void UserController::ClearAbilityUserItems(int32_t userId)
77{
78    std::lock_guard<ffrt::mutex> guard(userLock_);
79    if (userItems_.count(userId)) {
80        userItems_.erase(userId);
81    }
82}
83
84void UserController::StartUser(int32_t userId, sptr<IUserCallback> callback, bool isAppRecovery)
85{
86    if (userId < 0 || userId == USER_ID_NO_HEAD) {
87        TAG_LOGE(AAFwkTag::ABILITYMGR, "StartUserId invalid:%{public}d", userId);
88        callback->OnStartUserDone(userId, INVALID_USERID_VALUE);
89        return;
90    }
91
92    if (IsCurrentUser(userId)) {
93        TAG_LOGW(AAFwkTag::ABILITYMGR, "StartUser current:%{public}d", userId);
94        callback->OnStartUserDone(userId, ERR_OK);
95        return;
96    }
97
98    auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
99    if (!appScheduler) {
100        TAG_LOGE(AAFwkTag::ABILITYMGR, "null appScheduler");
101        return;
102    }
103    appScheduler->SetEnableStartProcessFlagByUserId(userId, true);
104
105    if (!IsExistOsAccount(userId)) {
106        TAG_LOGE(AAFwkTag::ABILITYMGR, "null StartUser account:%{public}d", userId);
107        callback->OnStartUserDone(userId, INVALID_USERID_VALUE);
108        return;
109    }
110
111    if (GetCurrentUserId() != USER_ID_NO_HEAD && !Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
112        // start freezing screen
113        SetFreezingNewUserId(userId);
114        DelayedSingleton<AbilityManagerService>::GetInstance()->StartFreezingScreen();
115    }
116
117    auto oldUserId = GetCurrentUserId();
118    auto userItem = GetOrCreateUserItem(userId);
119    auto state = userItem->GetState();
120    if (state == STATE_STOPPING || state == STATE_SHUTDOWN) {
121        TAG_LOGE(AAFwkTag::ABILITYMGR, "StartUser user stop, userId:%{public}d", userId);
122        callback->OnStartUserDone(userId, ERR_DEAD_OBJECT);
123        return;
124    }
125
126    SetCurrentUserId(userId);
127    // notify wms switching now
128
129    bool needStart = false;
130    if (state == STATE_BOOTING) {
131        needStart = true;
132        // send user start msg.
133        SendSystemUserStart(userId);
134    }
135
136    SendSystemUserCurrent(oldUserId, userId);
137    SendReportUserSwitch(oldUserId, userId, userItem);
138    SendUserSwitchTimeout(oldUserId, userId, userItem);
139
140    if (needStart) {
141        BroadcastUserStarted(userId);
142    }
143
144    UserBootDone(userItem);
145    MoveUserToForeground(oldUserId, userId, callback, isAppRecovery);
146}
147
148int32_t UserController::StopUser(int32_t userId)
149{
150    if (userId < 0 || userId == USER_ID_NO_HEAD || userId == USER_ID_DEFAULT) {
151        TAG_LOGE(AAFwkTag::ABILITYMGR, "userId invalid:%{public}d", userId);
152        return -1;
153    }
154
155    if (IsCurrentUser(userId)) {
156        TAG_LOGW(AAFwkTag::ABILITYMGR, "user current:%{public}d", userId);
157        return 0;
158    }
159
160    if (!IsExistOsAccount(userId)) {
161        TAG_LOGE(AAFwkTag::ABILITYMGR, "null account:%{public}d", userId);
162        return -1;
163    }
164
165    BroadcastUserStopping(userId);
166
167    auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
168    if (!appScheduler) {
169        TAG_LOGE(AAFwkTag::ABILITYMGR, "null appScheduler");
170        return -1;
171    }
172    appScheduler->KillProcessesByUserId(userId);
173
174    auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
175    if (!abilityManagerService) {
176        TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityManagerService null");
177        return -1;
178    }
179
180    if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
181        auto missionListWrap = abilityManagerService->GetMissionListWrap();
182        if (!missionListWrap) {
183            TAG_LOGE(AAFwkTag::ABILITYMGR, "missionListWrap null");
184            return -1;
185        }
186        missionListWrap->RemoveUserDir(userId);
187    }
188
189    abilityManagerService->ClearUserData(userId);
190
191    BroadcastUserStopped(userId);
192    return 0;
193}
194
195int32_t UserController::LogoutUser(int32_t userId)
196{
197    if (userId < 0 || userId == USER_ID_NO_HEAD) {
198        TAG_LOGE(AAFwkTag::ABILITYMGR, "userId invalid:%{public}d", userId);
199        return INVALID_USERID_VALUE;
200    }
201    if (!IsExistOsAccount(userId)) {
202        TAG_LOGE(AAFwkTag::ABILITYMGR, "null account:%{public}d", userId);
203        return INVALID_USERID_VALUE;
204    }
205    auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
206    if (!abilityManagerService) {
207        TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityManagerService");
208        return -1;
209    }
210    abilityManagerService->RemoveLauncherDeathRecipient(userId);
211    if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
212        TAG_LOGI(AAFwkTag::ABILITYMGR, "SceneBoard exit normally.");
213        Rosen::MockSessionManagerService::GetInstance().NotifyNotKillService();
214    }
215    auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
216    if (!appScheduler) {
217        TAG_LOGE(AAFwkTag::ABILITYMGR, "null appScheduler");
218        return INVALID_USERID_VALUE;
219    }
220    abilityManagerService->ClearUserData(userId);
221    appScheduler->SetEnableStartProcessFlagByUserId(userId, false);
222    if (IsCurrentUser(userId)) {
223        SetCurrentUserId(0);
224    }
225    appScheduler->KillProcessesByUserId(userId);
226    ClearAbilityUserItems(userId);
227    return 0;
228}
229
230int32_t UserController::GetCurrentUserId()
231{
232    std::lock_guard<ffrt::mutex> guard(userLock_);
233    return currentUserId_;
234}
235
236std::shared_ptr<UserItem> UserController::GetUserItem(int32_t userId)
237{
238    std::lock_guard<ffrt::mutex> guard(userLock_);
239    auto it = userItems_.find(userId);
240    if (it != userItems_.end()) {
241        return it->second;
242    }
243
244    return nullptr;
245}
246
247bool UserController::IsCurrentUser(int32_t userId)
248{
249    int32_t oldUserId = GetCurrentUserId();
250    if (oldUserId == userId) {
251        auto userItem = GetUserItem(userId);
252        if (userItem) {
253            TAG_LOGW(AAFwkTag::ABILITYMGR, "IsCurrentUserId current:%{public}d", userId);
254            return true;
255        }
256    }
257    return false;
258}
259
260bool UserController::IsExistOsAccount(int32_t userId)
261{
262    bool isExist = false;
263    auto errCode = DelayedSingleton<OsAccountManagerWrapper>::GetInstance()->IsOsAccountExists(userId, isExist);
264    return (errCode == 0) && isExist;
265}
266
267std::shared_ptr<UserItem> UserController::GetOrCreateUserItem(int32_t userId)
268{
269    std::lock_guard<ffrt::mutex> guard(userLock_);
270    auto it = userItems_.find(userId);
271    if (it != userItems_.end()) {
272        return it->second;
273    }
274
275    auto userItem = std::make_shared<UserItem>(userId);
276    userItems_.emplace(userId, userItem);
277    return userItem;
278}
279
280void UserController::SetCurrentUserId(int32_t userId)
281{
282    std::lock_guard<ffrt::mutex> guard(userLock_);
283    currentUserId_ = userId;
284    TAG_LOGD(AAFwkTag::ABILITYMGR, "set current userId: %{public}d", userId);
285    DelayedSingleton<AppScheduler>::GetInstance()->SetCurrentUserId(userId);
286}
287
288void UserController::MoveUserToForeground(int32_t oldUserId, int32_t newUserId, sptr<IUserCallback> callback,
289    bool isAppRecovery)
290{
291    auto manager = DelayedSingleton<AbilityManagerService>::GetInstance();
292    if (!manager) {
293        return;
294    }
295    manager->SwitchToUser(oldUserId, newUserId, callback, isAppRecovery);
296    BroadcastUserBackground(oldUserId);
297    BroadcastUserForeground(newUserId);
298}
299
300void UserController::UserBootDone(std::shared_ptr<UserItem> &item)
301{
302    if (!item) {
303        return;
304    }
305    int32_t userId = item->GetUserId();
306
307    std::lock_guard<ffrt::mutex> guard(userLock_);
308    auto it = userItems_.find(userId);
309    if (it != userItems_.end()) {
310        return;
311    }
312
313    if (item != it->second) {
314        return;
315    }
316    item->SetState(UserState::STATE_STARTED);
317    auto manager = DelayedSingleton<AbilityManagerService>::GetInstance();
318    if (!manager) {
319        return;
320    }
321    manager->UserStarted(userId);
322}
323
324void UserController::BroadcastUserStarted(int32_t userId)
325{
326    // broadcast event user start.
327}
328
329void UserController::BroadcastUserBackground(int32_t userId)
330{
331    // broadcast event user switch to bg.
332}
333
334void UserController::BroadcastUserForeground(int32_t userId)
335{
336    // broadcast event user switch to fg.
337}
338
339void UserController::BroadcastUserStopping(int32_t userId)
340{
341}
342
343void UserController::BroadcastUserStopped(int32_t userId)
344{
345}
346
347void UserController::SendSystemUserStart(int32_t userId)
348{
349    auto handler = eventHandler_;
350    if (!handler) {
351        return;
352    }
353
354    auto eventData = std::make_shared<UserEvent>();
355    eventData->newUserId = userId;
356    handler->SendEvent(EventWrap(UserEventHandler::EVENT_SYSTEM_USER_START, eventData));
357}
358
359void UserController::ProcessEvent(const EventWrap &event)
360{
361    auto eventId = event.GetEventId();
362    auto eventData = static_cast<UserEvent*>(event.GetEventData().get());
363    if (!eventData) {
364        TAG_LOGD(AAFwkTag::ABILITYMGR, "no event data, event id: %{public}u.", eventId);
365        return;
366    }
367
368    TAG_LOGD(AAFwkTag::ABILITYMGR, "Event id obtained: %{public}u.", eventId);
369    switch (eventId) {
370        case UserEventHandler::EVENT_SYSTEM_USER_START: {
371            HandleSystemUserStart(eventData->newUserId);
372            break;
373        }
374        case UserEventHandler::EVENT_SYSTEM_USER_CURRENT: {
375            HandleSystemUserCurrent(eventData->oldUserId, eventData->newUserId);
376            break;
377        }
378        case UserEventHandler::EVENT_REPORT_USER_SWITCH: {
379            HandleReportUserSwitch(eventData->oldUserId, eventData->newUserId, eventData->userItem);
380            break;
381        }
382        case UserEventHandler::EVENT_CONTINUE_USER_SWITCH: {
383            HandleContinueUserSwitch(eventData->oldUserId, eventData->newUserId, eventData->userItem);
384            break;
385        }
386        case UserEventHandler::EVENT_USER_SWITCH_TIMEOUT: {
387            HandleUserSwitchTimeout(eventData->oldUserId, eventData->newUserId, eventData->userItem);
388            break;
389        }
390        case UserEventHandler::EVENT_REPORT_USER_SWITCH_DONE: {
391            HandleUserSwitchDone(eventData->newUserId);
392            break;
393        }
394        default: {
395            TAG_LOGW(AAFwkTag::ABILITYMGR, "Unsupported  event.");
396            break;
397        }
398    }
399}
400
401void UserController::SendSystemUserCurrent(int32_t oldUserId, int32_t newUserId)
402{
403    auto handler = eventHandler_;
404    if (!handler) {
405        return;
406    }
407
408    auto eventData = std::make_shared<UserEvent>();
409    eventData->oldUserId = oldUserId;
410    eventData->newUserId = newUserId;
411    handler->SendEvent(EventWrap(UserEventHandler::EVENT_SYSTEM_USER_CURRENT, eventData));
412}
413
414void UserController::SendReportUserSwitch(int32_t oldUserId, int32_t newUserId,
415    std::shared_ptr<UserItem> &usrItem)
416{
417    auto handler = eventHandler_;
418    if (!handler) {
419        return;
420    }
421
422    auto eventData = std::make_shared<UserEvent>();
423    eventData->oldUserId = oldUserId;
424    eventData->newUserId = newUserId;
425    eventData->userItem = usrItem;
426    handler->SendEvent(EventWrap(UserEventHandler::EVENT_REPORT_USER_SWITCH, eventData));
427}
428
429void UserController::SendUserSwitchTimeout(int32_t oldUserId, int32_t newUserId,
430    std::shared_ptr<UserItem> &usrItem)
431{
432    auto handler = eventHandler_;
433    if (!handler) {
434        return;
435    }
436
437    auto eventData = std::make_shared<UserEvent>();
438    eventData->oldUserId = oldUserId;
439    eventData->newUserId = newUserId;
440    eventData->userItem = usrItem;
441    handler->SendEvent(EventWrap(UserEventHandler::EVENT_USER_SWITCH_TIMEOUT,
442        eventData), USER_SWITCH_TIMEOUT);
443}
444
445void UserController::SendContinueUserSwitch(int32_t oldUserId, int32_t newUserId,
446    std::shared_ptr<UserItem> &usrItem)
447{
448    auto handler = eventHandler_;
449    if (!handler) {
450        return;
451    }
452
453    auto eventData = std::make_shared<UserEvent>();
454    eventData->oldUserId = oldUserId;
455    eventData->newUserId = newUserId;
456    eventData->userItem = usrItem;
457    handler->SendEvent(EventWrap(UserEventHandler::EVENT_CONTINUE_USER_SWITCH, eventData));
458}
459
460void UserController::SendUserSwitchDone(int32_t userId)
461{
462    auto handler = eventHandler_;
463    if (!handler) {
464        return;
465    }
466
467    auto eventData = std::make_shared<UserEvent>();
468    eventData->newUserId = userId;
469    handler->SendEvent(EventWrap(UserEventHandler::EVENT_REPORT_USER_SWITCH_DONE,
470        eventData));
471}
472
473void UserController::HandleSystemUserStart(int32_t userId)
474{
475    // notify system mgr user start.
476}
477
478void UserController::HandleSystemUserCurrent(int32_t oldUserId, int32_t newUserId)
479{
480    // notify system mgr user switch to new.
481}
482
483void UserController::HandleReportUserSwitch(int32_t oldUserId, int32_t newUserId,
484    std::shared_ptr<UserItem> &usrItem)
485{
486    // notify user switch observers, not support yet.
487}
488
489void UserController::HandleUserSwitchTimeout(int32_t oldUserId, int32_t newUserId,
490    std::shared_ptr<UserItem> &usrItem)
491{
492    // other observers
493    SendContinueUserSwitch(oldUserId, newUserId, usrItem);
494}
495
496void UserController::HandleContinueUserSwitch(int32_t oldUserId, int32_t newUserId,
497    std::shared_ptr<UserItem> &usrItem)
498{
499    auto manager = DelayedSingleton<AbilityManagerService>::GetInstance();
500    if (manager && !Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
501        manager->StopFreezingScreen();
502    }
503    SendUserSwitchDone(newUserId);
504}
505
506void UserController::HandleUserSwitchDone(int32_t userId)
507{
508    // notify wms switching done.
509    // notify user switch observers.
510}
511
512int32_t UserController::GetFreezingNewUserId() const
513{
514    return freezingNewUserId_;
515}
516
517void UserController::SetFreezingNewUserId(int32_t userId)
518{
519    freezingNewUserId_ = userId;
520}
521}
522}
523