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 {createOrGet} from "./SingleInstanceHelper"; 19 20const TAG = "SwitchUserManagerSc"; 21const SUBSCRIBE_KEY = "SystemUiAccount"; 22const USER_CHANGE_EVENT = "activate"; 23const DELAY_TIME = 50 * 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 Log.showInfo(TAG, `accountInfos size:${accountInfos.length}`); 45 for (let accountInfo of accountInfos) { 46 Log.showDebug(TAG, `accountInfo: ${accountInfo.localId}, isActive: ${accountInfo.isActived}`); 47 if (accountInfo.isActived) { 48 return accountInfo; 49 } 50 } 51 return Promise.reject("Can't get active userInfo."); 52} 53 54function parseAccountInfo(accountInfo: AccountInfo): UserInfo { 55 return { 56 userId: accountInfo.localId, 57 userName: accountInfo.localName, 58 userIcon: accountInfo.photo, 59 }; 60} 61 62export class SwitchUserManager { 63 mUserInfo: UserInfo = new UserInfo(); 64 mListeners = new Set<UserChangeListener>(); 65 mHasWait: boolean = false; 66 67 static getInstance(): SwitchUserManager { 68 return createOrGet(SwitchUserManager, TAG); 69 } 70 71 constructor() { 72 Log.showDebug(TAG, `SwitchUserManager constructor`); 73 AccountManager.getAccountManager().on(USER_CHANGE_EVENT, SUBSCRIBE_KEY, this.handleUserChange.bind(this)); 74 } 75 76 public async getCurrentUserInfo(): Promise<UserInfo> { 77 if (this.mUserInfo.userId == INVALID_USER_ID) { 78 !this.mHasWait && (await new Promise((resolve) => setTimeout(resolve, DELAY_TIME))); 79 this.mHasWait = true; 80 this.mUserInfo = parseAccountInfo(await getCurrentAccountInfo()); 81 } 82 Log.showInfo(TAG, `getCurrentUserInfo userId: ${this.mUserInfo.userId}`); 83 return this.mUserInfo; 84 } 85 86 public registerListener(listener: UserChangeListener) { 87 this.mListeners.add(listener); 88 } 89 90 public unregisterListener(listener: UserChangeListener) { 91 this.mListeners.delete(listener); 92 } 93 94 handleUserChange(accountId: number): void { 95 AccountManager.getAccountManager() 96 .queryOsAccountById(accountId) 97 .then((accountInfo) => { 98 Log.showInfo(TAG, `userChange, accountInfo: ${JSON.stringify(accountInfo)}`); 99 this.mUserInfo = parseAccountInfo(accountInfo); 100 this.notifyUserChange(); 101 }) 102 .catch((err) => Log.showError(TAG, `Can't query account by ${accountId}, err: ${err}`)); 103 } 104 105 notifyUserChange() { 106 this.mListeners.forEach((listener) => listener.userChange(this.mUserInfo)); 107 } 108}