/*
* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CheckEmptyUtils, LogDomain, LogHelper } from '@ohos/basicutils';
import { ResourceManager } from '@ohos/frameworkwrapper';
import {
AppItemInfo,
AppModel,
GridLayoutItemInfo,
LaunchLayoutCacheManager,
} from '../../TsIndex';
import { OuterAppManager } from '../../manager/OuterAppManager';
import { intl } from '@kit.LocalizationKit';
import { taskpool } from '@kit.ArkTS';
const TAG: string = 'OuterIconCenterViewModel';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.HOME, TAG);
/**
* 外屏应用管理Model
*/
export class OuterIconCenterViewModel {
private static mInstance: OuterIconCenterViewModel;
private appInfoAllList: AppItemInfo[] = [];
// 所有应用,包括外屏已添加的应用
private appInfoAllListByAdded: AppItemInfo[] = [];
private topAppList: AppItemInfo[] = [];
private experimentAppList: AppItemInfo[] = [];
private nameMap: Map<string, string> = new Map();
private readonly mOuterAppManager: OuterAppManager = OuterAppManager.getInstance();
private collator: intl.Collator | undefined;
private options: intl.CollatorOptions = {
localeMatcher: 'lookup',
usage: 'sort',
numeric: true,
caseFirst: 'lower',
sensitivity: 'case',
collation: 'phonebk',
};
/**
* 获取 OuterIconCenterViewModel 实例
*
* @returns OuterIconCenterViewModel实例
*/
public static getInstance(): OuterIconCenterViewModel {
if (OuterIconCenterViewModel.mInstance == null) {
OuterIconCenterViewModel.mInstance = new OuterIconCenterViewModel();
}
return OuterIconCenterViewModel.mInstance;
}
/**
* 获取App列表
*
* @returns App列表
*/
public getAppInfoList(): AppItemInfo[] {
log.showInfo(`getAppInfoList appInfoAllList: ${this.appInfoAllList.length}`);
return this.appInfoAllList;
}
/**
* 获得新形态小折叠外屏所有应用,包括已添加至外屏桌面的应用
*
* @returns App列表
*/
public getAllListByAdded(): AppItemInfo[] {
log.showInfo(`getAllListByAdded: ${this.appInfoAllListByAdded.length}`);
return this.appInfoAllListByAdded;
}
/**
* 获得精品应用
*
* @returns 精品应用
*/
public getTopQualityPkgList(): AppItemInfo[] {
return this.topAppList;
}
/**
* 获得实验应用,需要初始化再使用
*
* @returns 实验应用
*/
public getPoorExperimentalPkgList(): AppItemInfo[] {
return this.experimentAppList;
}
/**
* 获取包名与小写转换后的应用名称map
*/
public getLowerCaseAppNameMap(): Map<string, string> {
return this.nameMap;
}
/**
* 更新应用中心
*
* @returns
*/
public async updateOuterIconCenterData(): Promise<void> {
this.mOuterAppManager.updateNameList();
log.showWarn('The refresh time is not reached.');
let appList: AppItemInfo[] = AppModel.getInstance().getAppList();
this.nameMap.clear();
for (let i = 0; i < appList.length; i++) {
appList[i].applicationName = await ResourceManager.getInstance()
.getAppNameSync(appList[i].appLabelId, appList[i].bundleName, appList[i].moduleName, '');
}
taskpool.execute(asyncGetAppTagInfos, appList).then((item) => {
let tmpItem = item as Map<string, string>;
this.nameMap = tmpItem;
});
let outerList: GridLayoutItemInfo[] = LaunchLayoutCacheManager.getInstance().getOuterList();
this.sortLocale(appList);
let appListFilterOuter: AppItemInfo[] = appList.filter((item) => {
return !outerList.some(itemSelect => itemSelect.bundleName === item.bundleName &&
itemSelect.appIndex === item.appIndex &&
itemSelect.typeId === 0);
});
this.topAppList = [];
this.experimentAppList = [];
let topAppNameList: string[] = this.mOuterAppManager.getTopPkgNameListByTag();
let experimentAppNameList: string[] = this.mOuterAppManager.getExperimentalPkgNameListByTag();
appList.forEach(item => {
if (CheckEmptyUtils.isEmpty(item) || topAppNameList.includes(item.bundleName) ||
experimentAppNameList.includes(item.bundleName)) {
return;
}
if (this.mOuterAppManager.isTopApp(item.bundleName)) {
topAppNameList.push(item.bundleName);
return;
}
if (this.mOuterAppManager.isOpenVersion(true) &&
!this.mOuterAppManager.isBlockApp(item.bundleName, undefined, true)) {
experimentAppNameList.push(item.bundleName);
return;
}
});
appListFilterOuter.forEach(item => {
if (topAppNameList.indexOf(item.bundleName) !== -1) {
this.topAppList.push(item);
} else if (experimentAppNameList.indexOf(item.bundleName) !== -1) {
this.experimentAppList.push(item);
}
});
this.appInfoAllList = this.topAppList.concat(this.experimentAppList);
this.appInfoAllListByAdded = appList.filter(item => {
return (topAppNameList.indexOf(item.bundleName) !== -1) ||
(experimentAppNameList.indexOf(item.bundleName) !== -1);
});
}
private sortLocale(appList: AppItemInfo[]): void {
if (appList.length === 0) {
return;
}
if (CheckEmptyUtils.isEmpty(this.collator)) {
this.collator = new intl.Collator(new intl.Locale().toString(), this.options);
}
appList.sort((appInfoFirst, appInfoSecond) => {
return this.collator?.compare(appInfoFirst.applicationName, appInfoSecond.applicationName) ?? 0;
});
}
}
async function asyncGetAppTagInfos(appItemInfos: AppItemInfo[]): Promise<Map<string, string>> {
'use concurrent';
let nameMap: Map<string, string> = new Map();
appItemInfos.forEach(item => {
if (item.applicationName) {
nameMap.set(item.bundleName, item.applicationName.toLocaleLowerCase());
}
});
return nameMap;
}