1e75ebbc8Sopenharmony_ci/*
2e75ebbc8Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3e75ebbc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e75ebbc8Sopenharmony_ci * you may not use this file except in compliance with the License.
5e75ebbc8Sopenharmony_ci * You may obtain a copy of the License at
6e75ebbc8Sopenharmony_ci *
7e75ebbc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e75ebbc8Sopenharmony_ci *
9e75ebbc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e75ebbc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e75ebbc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e75ebbc8Sopenharmony_ci * See the License for the specific language governing permissions and
13e75ebbc8Sopenharmony_ci * limitations under the License.
14e75ebbc8Sopenharmony_ci */
15e75ebbc8Sopenharmony_ci
16e75ebbc8Sopenharmony_ciimport AccountManager from "@ohos.account.osAccount";
17e75ebbc8Sopenharmony_ciimport Log from "./Log";
18e75ebbc8Sopenharmony_ciimport getSingleInstance from "./SingleInstanceHelper";
19e75ebbc8Sopenharmony_ci
20e75ebbc8Sopenharmony_ciconst TAG = "SwitchUserManager";
21e75ebbc8Sopenharmony_ciconst SUBSCRIBE_KEY = "SystemUiAccount";
22e75ebbc8Sopenharmony_ciconst USER_CHANGE_EVENT = "activate";
23e75ebbc8Sopenharmony_ciconst DELAY_TIME = 3 * 1000;
24e75ebbc8Sopenharmony_ciexport const INVALID_USER_ID = -1;
25e75ebbc8Sopenharmony_ci
26e75ebbc8Sopenharmony_citype AccountInfo = {
27e75ebbc8Sopenharmony_ci  localId: number;
28e75ebbc8Sopenharmony_ci  localName: string;
29e75ebbc8Sopenharmony_ci  photo: string;
30e75ebbc8Sopenharmony_ci};
31e75ebbc8Sopenharmony_ciexport type UserChangeListener = {
32e75ebbc8Sopenharmony_ci  userChange: (data: UserInfo) => void;
33e75ebbc8Sopenharmony_ci};
34e75ebbc8Sopenharmony_ci
35e75ebbc8Sopenharmony_ciexport class UserInfo {
36e75ebbc8Sopenharmony_ci  userId: number = INVALID_USER_ID;
37e75ebbc8Sopenharmony_ci  userName: string = "";
38e75ebbc8Sopenharmony_ci  userIcon: string | Resource = "";
39e75ebbc8Sopenharmony_ci  [key: string]: any;
40e75ebbc8Sopenharmony_ci}
41e75ebbc8Sopenharmony_ci
42e75ebbc8Sopenharmony_ciasync function getCurrentAccountInfo(): Promise<AccountInfo> {
43e75ebbc8Sopenharmony_ci  let accountInfos = await AccountManager.getAccountManager().queryAllCreatedOsAccounts();
44e75ebbc8Sopenharmony_ci  for (let accountInfo of accountInfos) {
45e75ebbc8Sopenharmony_ci    Log.showDebug(TAG, `accountInfo: ${accountInfo.localId}, isActive: ${accountInfo.isActived}`);
46e75ebbc8Sopenharmony_ci    if (accountInfo.isActived) {
47e75ebbc8Sopenharmony_ci      return accountInfo;
48e75ebbc8Sopenharmony_ci    }
49e75ebbc8Sopenharmony_ci  }
50e75ebbc8Sopenharmony_ci  return { localId: INVALID_USER_ID, localName: "", photo: "" };
51e75ebbc8Sopenharmony_ci}
52e75ebbc8Sopenharmony_ci
53e75ebbc8Sopenharmony_cifunction parseAccountInfo(accountInfo: AccountInfo): UserInfo {
54e75ebbc8Sopenharmony_ci  return {
55e75ebbc8Sopenharmony_ci    userId: accountInfo.localId,
56e75ebbc8Sopenharmony_ci    userName: accountInfo.localName,
57e75ebbc8Sopenharmony_ci    userIcon: accountInfo.photo,
58e75ebbc8Sopenharmony_ci  };
59e75ebbc8Sopenharmony_ci}
60e75ebbc8Sopenharmony_ci
61e75ebbc8Sopenharmony_ciexport default class SwitchUserManager {
62e75ebbc8Sopenharmony_ci  mUserInfo: UserInfo = new UserInfo();
63e75ebbc8Sopenharmony_ci  mListeners = new Set<UserChangeListener>();
64e75ebbc8Sopenharmony_ci  mHasWait: boolean = false;
65e75ebbc8Sopenharmony_ci
66e75ebbc8Sopenharmony_ci  static getInstance(): SwitchUserManager {
67e75ebbc8Sopenharmony_ci    return getSingleInstance(SwitchUserManager, TAG);
68e75ebbc8Sopenharmony_ci  }
69e75ebbc8Sopenharmony_ci
70e75ebbc8Sopenharmony_ci  constructor() {
71e75ebbc8Sopenharmony_ci    Log.showDebug(TAG, `SwitchUserManager constructor`);
72e75ebbc8Sopenharmony_ci    try {
73e75ebbc8Sopenharmony_ci      AccountManager.getAccountManager().on(USER_CHANGE_EVENT, SUBSCRIBE_KEY, this.handleUserChange.bind(this));
74e75ebbc8Sopenharmony_ci    } catch (err) {
75e75ebbc8Sopenharmony_ci      Log.showError(TAG, `AccountManager.getAccountManager().on error: ${JSON.stringify(err)}`);
76e75ebbc8Sopenharmony_ci    }
77e75ebbc8Sopenharmony_ci  }
78e75ebbc8Sopenharmony_ci
79e75ebbc8Sopenharmony_ci  public async getCurrentUserInfo(): Promise<UserInfo> {
80e75ebbc8Sopenharmony_ci    if (this.mUserInfo.userId == INVALID_USER_ID) {
81e75ebbc8Sopenharmony_ci      this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
82e75ebbc8Sopenharmony_ci      while (!this.mHasWait && this.mUserInfo.userId == INVALID_USER_ID) {
83e75ebbc8Sopenharmony_ci        await new Promise((resolve) => setTimeout(resolve, DELAY_TIME));
84e75ebbc8Sopenharmony_ci        this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
85e75ebbc8Sopenharmony_ci      }
86e75ebbc8Sopenharmony_ci      this.mHasWait = true;
87e75ebbc8Sopenharmony_ci      this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
88e75ebbc8Sopenharmony_ci    }
89e75ebbc8Sopenharmony_ci    Log.showDebug(TAG, `getCurrentUserInfo userId: ${this.mUserInfo.userId}`);
90e75ebbc8Sopenharmony_ci    return this.mUserInfo;
91e75ebbc8Sopenharmony_ci  }
92e75ebbc8Sopenharmony_ci
93e75ebbc8Sopenharmony_ci  public registerListener(listener: UserChangeListener) {
94e75ebbc8Sopenharmony_ci    this.mListeners.add(listener);
95e75ebbc8Sopenharmony_ci  }
96e75ebbc8Sopenharmony_ci
97e75ebbc8Sopenharmony_ci  public unregisterListener(listener: UserChangeListener) {
98e75ebbc8Sopenharmony_ci    this.mListeners.delete(listener);
99e75ebbc8Sopenharmony_ci  }
100e75ebbc8Sopenharmony_ci
101e75ebbc8Sopenharmony_ci  handleUserChange(accountId: number): void {
102e75ebbc8Sopenharmony_ci    AccountManager.getAccountManager()
103e75ebbc8Sopenharmony_ci      .queryOsAccountById(accountId)
104e75ebbc8Sopenharmony_ci      .then((accountInfo) => {
105e75ebbc8Sopenharmony_ci        Log.showInfo(TAG, `userChange, localId: ${accountInfo?.localId}`);
106e75ebbc8Sopenharmony_ci        this.mUserInfo = parseAccountInfo(accountInfo);
107e75ebbc8Sopenharmony_ci        this.notifyUserChange();
108e75ebbc8Sopenharmony_ci      })
109e75ebbc8Sopenharmony_ci      .catch((err) => Log.showError(TAG, `Can't query account by ${accountId}, err: ${err}`));
110e75ebbc8Sopenharmony_ci  }
111e75ebbc8Sopenharmony_ci
112e75ebbc8Sopenharmony_ci  notifyUserChange() {
113e75ebbc8Sopenharmony_ci    this.mListeners.forEach((listener) => listener.userChange(this.mUserInfo));
114e75ebbc8Sopenharmony_ci  }
115e75ebbc8Sopenharmony_ci}
116