/** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * 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 image from '@ohos.multimedia.image'; import missionManager from '@ohos.app.ability.missionManager'; import { Log } from '../utils/Log'; import { CheckEmptyUtils } from '../utils/CheckEmptyUtils'; import { launcherAbilityManager } from './LauncherAbilityManager'; import { SnapShotInfo } from '../bean/SnapShotInfo'; import { MissionInfo } from '../bean/MissionInfo'; import { RecentMissionInfo } from '../bean/RecentMissionInfo'; import { RecentBundleMissionInfo } from '../bean/RecentBundleMissionInfo'; import { windowManager } from './WindowManager'; const TAG = 'AmsMissionManager'; /** * missionManager for Launcher */ class AmsMissionManager { private static readonly RECENT_MISSIONS_LIMIT_NUM = 20; private mMissionId: number; private mLockState: boolean; static getInstance(): AmsMissionManager { if (globalThis.AmsMissionManagerInstance == null) { globalThis.AmsMissionManagerInstance = new AmsMissionManager(); // remove this if toolchain fix requireNApi bug image.toString(); } return globalThis.AmsMissionManagerInstance; } /** * Get origin recent missions * * @return {Array} missions */ async getOriginRecentMissionsList(): Promise> { try { let arrayMissionInfo = new Array(); let res = await missionManager.getMissionInfos('', AmsMissionManager.RECENT_MISSIONS_LIMIT_NUM); if (!CheckEmptyUtils.isEmptyArr(res)) { Log.showDebug(TAG, `getOriginRecentMissionsList res.length: ${res.length}`); arrayMissionInfo = res; return arrayMissionInfo; } } catch (err) { Log.showError(TAG, `getOriginRecentMissionsList fail, err: ${JSON.stringify(err)}`); } } /** * Get recent missions list * * @return {Array} missions list */ async getRecentMissionsList(): Promise> { const recentMissionsList = new Array(); let missionInfos: Array = await this.getOriginRecentMissionsList(); if (CheckEmptyUtils.isEmptyArr(missionInfos)) { Log.showDebug(TAG, 'getRecentMissionsList Empty'); return recentMissionsList; } for (const recentItem of missionInfos) { const recentMissionInfo = new RecentMissionInfo(); recentMissionInfo.missionId = recentItem.missionId; recentMissionInfo.bundleName = recentItem.want.bundleName; recentMissionInfo.abilityName = recentItem.want.abilityName; recentMissionInfo.moduleName = recentItem.want.parameters?.moduleName ? String(recentItem.want.parameters?.moduleName) : ''; recentMissionInfo.lockedState = recentItem.lockedState; recentMissionInfo.snapShotTime = recentItem.timestamp; const appInfo = await launcherAbilityManager.getAppInfoByBundleName(recentMissionInfo.bundleName, recentMissionInfo.abilityName); if (appInfo == undefined) { continue; } recentMissionInfo.appLabelId = appInfo.appLabelId; recentMissionInfo.appIconId = appInfo.appIconId; recentMissionInfo.appName = appInfo.appName; recentMissionsList.push(recentMissionInfo); } Log.showInfo(TAG, `getRecentMissionsList recentMissionsList length: ${recentMissionsList.length}`); return recentMissionsList; } /** * Get recent missions list group by bundleName * * @return {Array} missions list */ async getRecentBundleMissionsList(): Promise> { const recentMissionsList = new Array(); let missionInfos: Array = await this.getOriginRecentMissionsList(); if (CheckEmptyUtils.isEmptyArr(missionInfos)) { Log.showDebug(TAG, 'getRecentBundleMissionsList Empty'); return recentMissionsList; } for (let i = 0; i < missionInfos.length; i++) { let missionInfo = missionInfos[i]; let bundleName = missionInfo.want.bundleName!; let abilityName = missionInfo.want.abilityName!; let localMissionInfo = recentMissionsList.find((item) => item.bundleName === bundleName); if (localMissionInfo) { let missionInfoAdd = new MissionInfo(); missionInfoAdd.missionId = missionInfo.missionId; localMissionInfo.missionInfoList!.push(missionInfoAdd); } else { let recentTaskInfo = new RecentBundleMissionInfo(); recentTaskInfo.bundleName = bundleName; const appInfo = await launcherAbilityManager.getAppInfoByBundleName(bundleName, abilityName); if (appInfo == undefined) { continue; } recentTaskInfo.abilityName = appInfo.abilityName; recentTaskInfo.moduleName = appInfo.moduleName; recentTaskInfo.keyName = bundleName + appInfo.abilityName + appInfo.moduleName; recentTaskInfo.appLabelId = appInfo.appLabelId; recentTaskInfo.appIconId = appInfo.appIconId; recentTaskInfo.appName = appInfo.appName; recentTaskInfo.missionInfoList = new Array(); let missionInfoAdd = new MissionInfo(); missionInfoAdd.missionId = missionInfo.missionId; recentTaskInfo.missionInfoList.push(missionInfoAdd); recentMissionsList.push(recentTaskInfo); } } Log.showInfo(TAG, `getRecentBundleMissionsList recentMissionsList length:${recentMissionsList.length}`); return recentMissionsList; } /** * Clear the given mission in the ability manager service. * * @param missionId */ async clearMission(missionId: number): Promise { Log.showInfo(TAG, `clearMission Id:${missionId}`); try { await missionManager.clearMission(missionId); Log.showDebug(TAG, 'clearMission success'); } catch (err) { Log.showError(TAG, `clearMission fail, err:${JSON.stringify(err)}`); } } /** * Clear all missions in the ability manager service. * locked mission will not clear * * @return nothing. */ async clearAllMissions(): Promise { try { await missionManager.clearAllMissions(); Log.showDebug(TAG, 'clearAllMissions success'); } catch (err) { Log.showError(TAG, `clearAllMissions fail, err: ${JSON.stringify(err)}`); } } /** * lockMission * * @param missionId mission id to lock. */ lockMission(missionId: number): void { Log.showInfo(TAG, `lockMission start! missionId: ${missionId}`); this.mMissionId = missionId; this.mLockState = true; missionManager.lockMission(missionId, this.lockCallback.bind(this)); } /** * unlockMission * * @param missionId mission id to unlock. */ unlockMission(missionId: number): void { Log.showInfo(TAG, `unlockMission start! missionId: ${missionId}`); this.mMissionId = missionId; this.mLockState = false; missionManager.unlockMission(missionId, this.lockCallback.bind(this)); } private async lockCallback(): Promise { Log.showDebug(TAG, 'lockCallback start'); // update mission recent card let mRecentMissionsList = await amsMissionManager.getRecentMissionsList(); mRecentMissionsList.find(item => { return item.missionId === this.mMissionId; }).lockedState = this.mLockState; if (globalThis.recentMode && windowManager.isSplitWindowMode(globalThis.recentMode)) { mRecentMissionsList.forEach((item, index) => { if (item.missionId == globalThis.splitMissionId) { mRecentMissionsList.splice(index, 1); return; } }); } AppStorage.setOrCreate('recentMissionsList', mRecentMissionsList); }; /** * Get recent mission snapshot info * * @param missionId mission id to get snapshot. * @return snapshot info */ async getMissionSnapShot(missionId: number): Promise { let snapShotInfo: SnapShotInfo = new SnapShotInfo(); Log.showInfo(TAG, `getMissionSnapShot start! missionId: ${missionId}`); try { let missionSnapshot: missionManager.MissionSnapshot = null; missionSnapshot = await missionManager.getMissionSnapShot('', missionId); Log.showInfo(TAG, 'getMissionSnapShot end'); const imageInfo = await missionSnapshot.snapshot.getImageInfo(); Log.showDebug(TAG, `getMissionSnapShot ${missionId} success ${JSON.stringify(imageInfo)}`); snapShotInfo.missionId = missionId; snapShotInfo.snapShotImage = missionSnapshot.snapshot; snapShotInfo.snapShotImageWidth = imageInfo.size.width; snapShotInfo.snapShotImageHeight = imageInfo.size.height; } catch (err) { Log.showError(TAG, `missionManager.getMissionSnapShot fail, missionId:${missionId} err: ${JSON.stringify(err)}`); } return snapShotInfo; } /** * Move mission to front * * @param missionId */ async moveMissionToFront(missionId: number, winMode?: number) { Log.showInfo(TAG, `moveMissionToFront missionId: ${missionId}`); try { winMode ? await missionManager.moveMissionToFront(missionId, { windowMode: winMode }): await missionManager.moveMissionToFront(missionId); Log.showDebug(TAG, 'moveMissionToFront missionId end success'); } catch (err) { Log.showError(TAG, `moveMissionToFront fail, err: ${JSON.stringify(err)}`); } } } export const amsMissionManager = AmsMissionManager.getInstance();