• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 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
16import AccountManager from "@ohos.account.osAccount";
17import Log from "./Log";
18import getSingleInstance from "./SingleInstanceHelper";
19
20const TAG = "SwitchUserManager";
21const SUBSCRIBE_KEY = "SystemUiAccount";
22const USER_CHANGE_EVENT = "activate";
23const DELAY_TIME = 3 * 1000;
24export const INVALID_USER_ID = -1;
25
26type AccountInfo = {
27  localId: number;
28  localName: string;
29  photo: string;
30};
31export type UserChangeListener = {
32  userChange: (data: UserInfo) => void;
33};
34
35export class UserInfo {
36  userId: number = INVALID_USER_ID;
37  userName: string = "";
38  userIcon: string | Resource = "";
39  [key: string]: any;
40}
41
42async function getCurrentAccountInfo(): Promise<AccountInfo> {
43  let accountInfos = await AccountManager.getAccountManager().queryAllCreatedOsAccounts();
44  for (let accountInfo of accountInfos) {
45    Log.showDebug(TAG, `accountInfo: ${accountInfo.localId}, isActive: ${accountInfo.isActived}`);
46    if (accountInfo.isActived) {
47      return accountInfo;
48    }
49  }
50  return { localId: INVALID_USER_ID, localName: "", photo: "" };
51}
52
53function parseAccountInfo(accountInfo: AccountInfo): UserInfo {
54  return {
55    userId: accountInfo.localId,
56    userName: accountInfo.localName,
57    userIcon: accountInfo.photo,
58  };
59}
60
61export default class SwitchUserManager {
62  mUserInfo: UserInfo = new UserInfo();
63  mListeners = new Set<UserChangeListener>();
64  mHasWait: boolean = false;
65
66  static getInstance(): SwitchUserManager {
67    return getSingleInstance(SwitchUserManager, TAG);
68  }
69
70  constructor() {
71    Log.showDebug(TAG, `SwitchUserManager constructor`);
72    AccountManager.getAccountManager().on(USER_CHANGE_EVENT, SUBSCRIBE_KEY, this.handleUserChange.bind(this));
73  }
74
75  public async getCurrentUserInfo(): Promise<UserInfo> {
76    if (this.mUserInfo.userId == INVALID_USER_ID) {
77      this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
78      while (!this.mHasWait && this.mUserInfo.userId == INVALID_USER_ID) {
79        await new Promise((resolve) => setTimeout(resolve, DELAY_TIME));
80        this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
81      }
82      this.mHasWait = true;
83      this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo());
84    }
85    Log.showDebug(TAG, `getCurrentUserInfo userId: ${this.mUserInfo.userId}`);
86    return this.mUserInfo;
87  }
88
89  public registerListener(listener: UserChangeListener) {
90    this.mListeners.add(listener);
91  }
92
93  public unregisterListener(listener: UserChangeListener) {
94    this.mListeners.delete(listener);
95  }
96
97  handleUserChange(accountId: number): void {
98    AccountManager.getAccountManager()
99      .queryOsAccountById(accountId)
100      .then((accountInfo) => {
101        Log.showInfo(TAG, `userChange, localId: ${accountInfo?.localId}`);
102        this.mUserInfo = parseAccountInfo(accountInfo);
103        this.notifyUserChange();
104      })
105      .catch((err) => Log.showError(TAG, `Can't query account by ${accountId}, err: ${err}`));
106  }
107
108  notifyUserChange() {
109    this.mListeners.forEach((listener) => listener.userChange(this.mUserInfo));
110  }
111}
112