16e80583aSopenharmony_ci/**
26e80583aSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
36e80583aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46e80583aSopenharmony_ci * you may not use this file except in compliance with the License.
56e80583aSopenharmony_ci * You may obtain a copy of the License at
66e80583aSopenharmony_ci *
76e80583aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
86e80583aSopenharmony_ci *
96e80583aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106e80583aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116e80583aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126e80583aSopenharmony_ci * See the License for the specific language governing permissions and
136e80583aSopenharmony_ci * limitations under the License.
146e80583aSopenharmony_ci */
156e80583aSopenharmony_ci
166e80583aSopenharmony_ciimport image from '@ohos.multimedia.image';
176e80583aSopenharmony_ciimport missionManager from '@ohos.app.ability.missionManager';
186e80583aSopenharmony_ciimport { Log } from '../utils/Log';
196e80583aSopenharmony_ciimport { CheckEmptyUtils } from '../utils/CheckEmptyUtils';
206e80583aSopenharmony_ciimport { launcherAbilityManager } from './LauncherAbilityManager';
216e80583aSopenharmony_ciimport { SnapShotInfo } from '../bean/SnapShotInfo';
226e80583aSopenharmony_ciimport { MissionInfo } from '../bean/MissionInfo';
236e80583aSopenharmony_ciimport { RecentMissionInfo } from '../bean/RecentMissionInfo';
246e80583aSopenharmony_ciimport { RecentBundleMissionInfo } from '../bean/RecentBundleMissionInfo';
256e80583aSopenharmony_ciimport { windowManager } from './WindowManager';
266e80583aSopenharmony_ci
276e80583aSopenharmony_ciconst TAG = 'AmsMissionManager';
286e80583aSopenharmony_ci
296e80583aSopenharmony_ci/**
306e80583aSopenharmony_ci * missionManager for Launcher
316e80583aSopenharmony_ci */
326e80583aSopenharmony_ciclass AmsMissionManager {
336e80583aSopenharmony_ci  private static readonly RECENT_MISSIONS_LIMIT_NUM = 20;
346e80583aSopenharmony_ci  private mMissionId: number;
356e80583aSopenharmony_ci  private mLockState: boolean;
366e80583aSopenharmony_ci
376e80583aSopenharmony_ci  static getInstance(): AmsMissionManager {
386e80583aSopenharmony_ci    if (globalThis.AmsMissionManagerInstance == null) {
396e80583aSopenharmony_ci      globalThis.AmsMissionManagerInstance = new AmsMissionManager();
406e80583aSopenharmony_ci      // remove this if toolchain fix requireNApi bug
416e80583aSopenharmony_ci      image.toString();
426e80583aSopenharmony_ci    }
436e80583aSopenharmony_ci    return globalThis.AmsMissionManagerInstance;
446e80583aSopenharmony_ci  }
456e80583aSopenharmony_ci
466e80583aSopenharmony_ci
476e80583aSopenharmony_ci  /**
486e80583aSopenharmony_ci   * Get origin recent missions
496e80583aSopenharmony_ci   *
506e80583aSopenharmony_ci   * @return {Array} missions
516e80583aSopenharmony_ci   */
526e80583aSopenharmony_ci  async getOriginRecentMissionsList(): Promise<Array<missionManager.MissionInfo>> {
536e80583aSopenharmony_ci    try {
546e80583aSopenharmony_ci      let arrayMissionInfo = new Array<missionManager.MissionInfo>();
556e80583aSopenharmony_ci      let res = await missionManager.getMissionInfos('', AmsMissionManager.RECENT_MISSIONS_LIMIT_NUM);
566e80583aSopenharmony_ci      if (!CheckEmptyUtils.isEmptyArr(res)) {
576e80583aSopenharmony_ci        Log.showDebug(TAG, `getOriginRecentMissionsList res.length: ${res.length}`);
586e80583aSopenharmony_ci        arrayMissionInfo = res;
596e80583aSopenharmony_ci        return arrayMissionInfo;
606e80583aSopenharmony_ci      }
616e80583aSopenharmony_ci    } catch (err) {
626e80583aSopenharmony_ci      Log.showError(TAG, `getOriginRecentMissionsList fail, err: ${JSON.stringify(err)}`);
636e80583aSopenharmony_ci    }
646e80583aSopenharmony_ci  }
656e80583aSopenharmony_ci
666e80583aSopenharmony_ci  /**
676e80583aSopenharmony_ci   * Get recent missions list
686e80583aSopenharmony_ci   *
696e80583aSopenharmony_ci   * @return {Array} missions list
706e80583aSopenharmony_ci   */
716e80583aSopenharmony_ci  async getRecentMissionsList(): Promise<Array<RecentMissionInfo>> {
726e80583aSopenharmony_ci    const recentMissionsList = new Array<RecentMissionInfo>();
736e80583aSopenharmony_ci    let missionInfos: Array<missionManager.MissionInfo> = await this.getOriginRecentMissionsList();
746e80583aSopenharmony_ci    if (CheckEmptyUtils.isEmptyArr(missionInfos)) {
756e80583aSopenharmony_ci      Log.showDebug(TAG, 'getRecentMissionsList Empty');
766e80583aSopenharmony_ci      return recentMissionsList;
776e80583aSopenharmony_ci    }
786e80583aSopenharmony_ci    for (const recentItem of missionInfos) {
796e80583aSopenharmony_ci      const recentMissionInfo = new RecentMissionInfo();
806e80583aSopenharmony_ci      recentMissionInfo.missionId = recentItem.missionId;
816e80583aSopenharmony_ci      recentMissionInfo.bundleName = recentItem.want.bundleName;
826e80583aSopenharmony_ci      recentMissionInfo.abilityName = recentItem.want.abilityName;
836e80583aSopenharmony_ci      recentMissionInfo.moduleName = recentItem.want.parameters?.moduleName ? String(recentItem.want.parameters?.moduleName) : '';
846e80583aSopenharmony_ci      recentMissionInfo.lockedState = recentItem.lockedState;
856e80583aSopenharmony_ci      recentMissionInfo.snapShotTime = recentItem.timestamp;
866e80583aSopenharmony_ci      const appInfo = await launcherAbilityManager.getAppInfoByBundleName(recentMissionInfo.bundleName, recentMissionInfo.abilityName);
876e80583aSopenharmony_ci      if (appInfo == undefined) {
886e80583aSopenharmony_ci        continue;
896e80583aSopenharmony_ci      }
906e80583aSopenharmony_ci      recentMissionInfo.appLabelId = appInfo.appLabelId;
916e80583aSopenharmony_ci      recentMissionInfo.appIconId = appInfo.appIconId;
926e80583aSopenharmony_ci      recentMissionInfo.appName = appInfo.appName;
936e80583aSopenharmony_ci      recentMissionsList.push(recentMissionInfo);
946e80583aSopenharmony_ci    }
956e80583aSopenharmony_ci    Log.showInfo(TAG, `getRecentMissionsList recentMissionsList length: ${recentMissionsList.length}`);
966e80583aSopenharmony_ci    return recentMissionsList;
976e80583aSopenharmony_ci  }
986e80583aSopenharmony_ci
996e80583aSopenharmony_ci  /**
1006e80583aSopenharmony_ci   * Get recent missions list group by bundleName
1016e80583aSopenharmony_ci   *
1026e80583aSopenharmony_ci   * @return {Array} missions list
1036e80583aSopenharmony_ci   */
1046e80583aSopenharmony_ci  async getRecentBundleMissionsList(): Promise<Array<RecentBundleMissionInfo>> {
1056e80583aSopenharmony_ci    const recentMissionsList = new Array<RecentBundleMissionInfo>();
1066e80583aSopenharmony_ci    let missionInfos: Array<missionManager.MissionInfo> = await this.getOriginRecentMissionsList();
1076e80583aSopenharmony_ci    if (CheckEmptyUtils.isEmptyArr(missionInfos)) {
1086e80583aSopenharmony_ci      Log.showDebug(TAG, 'getRecentBundleMissionsList Empty');
1096e80583aSopenharmony_ci      return recentMissionsList;
1106e80583aSopenharmony_ci    }
1116e80583aSopenharmony_ci    for (let i = 0; i < missionInfos.length; i++) {
1126e80583aSopenharmony_ci      let missionInfo = missionInfos[i];
1136e80583aSopenharmony_ci      let bundleName = missionInfo.want.bundleName!;
1146e80583aSopenharmony_ci      let abilityName = missionInfo.want.abilityName!;
1156e80583aSopenharmony_ci      let localMissionInfo = recentMissionsList.find((item) => item.bundleName === bundleName);
1166e80583aSopenharmony_ci      if (localMissionInfo) {
1176e80583aSopenharmony_ci        let missionInfoAdd = new MissionInfo();
1186e80583aSopenharmony_ci        missionInfoAdd.missionId = missionInfo.missionId;
1196e80583aSopenharmony_ci        localMissionInfo.missionInfoList!.push(missionInfoAdd);
1206e80583aSopenharmony_ci      } else {
1216e80583aSopenharmony_ci        let recentTaskInfo = new RecentBundleMissionInfo();
1226e80583aSopenharmony_ci        recentTaskInfo.bundleName = bundleName;
1236e80583aSopenharmony_ci        const appInfo = await launcherAbilityManager.getAppInfoByBundleName(bundleName, abilityName);
1246e80583aSopenharmony_ci        if (appInfo == undefined) {
1256e80583aSopenharmony_ci          continue;
1266e80583aSopenharmony_ci        }
1276e80583aSopenharmony_ci        recentTaskInfo.abilityName = appInfo.abilityName;
1286e80583aSopenharmony_ci        recentTaskInfo.moduleName = appInfo.moduleName;
1296e80583aSopenharmony_ci        recentTaskInfo.keyName = bundleName + appInfo.abilityName + appInfo.moduleName;
1306e80583aSopenharmony_ci        recentTaskInfo.appLabelId = appInfo.appLabelId;
1316e80583aSopenharmony_ci        recentTaskInfo.appIconId = appInfo.appIconId;
1326e80583aSopenharmony_ci        recentTaskInfo.appName = appInfo.appName;
1336e80583aSopenharmony_ci        recentTaskInfo.missionInfoList = new Array<MissionInfo>();
1346e80583aSopenharmony_ci        let missionInfoAdd = new MissionInfo();
1356e80583aSopenharmony_ci        missionInfoAdd.missionId = missionInfo.missionId;
1366e80583aSopenharmony_ci        recentTaskInfo.missionInfoList.push(missionInfoAdd);
1376e80583aSopenharmony_ci        recentMissionsList.push(recentTaskInfo);
1386e80583aSopenharmony_ci      }
1396e80583aSopenharmony_ci    }
1406e80583aSopenharmony_ci    Log.showInfo(TAG, `getRecentBundleMissionsList recentMissionsList length:${recentMissionsList.length}`);
1416e80583aSopenharmony_ci    return recentMissionsList;
1426e80583aSopenharmony_ci  }
1436e80583aSopenharmony_ci
1446e80583aSopenharmony_ci  /**
1456e80583aSopenharmony_ci   * Clear the given mission in the ability manager service.
1466e80583aSopenharmony_ci   *
1476e80583aSopenharmony_ci   * @param missionId
1486e80583aSopenharmony_ci   */
1496e80583aSopenharmony_ci  async clearMission(missionId: number): Promise<void> {
1506e80583aSopenharmony_ci    Log.showInfo(TAG, `clearMission Id:${missionId}`);
1516e80583aSopenharmony_ci    try {
1526e80583aSopenharmony_ci      await missionManager.clearMission(missionId);
1536e80583aSopenharmony_ci      Log.showDebug(TAG, 'clearMission success');
1546e80583aSopenharmony_ci    } catch (err) {
1556e80583aSopenharmony_ci      Log.showError(TAG, `clearMission fail, err:${JSON.stringify(err)}`);
1566e80583aSopenharmony_ci    }
1576e80583aSopenharmony_ci  }
1586e80583aSopenharmony_ci
1596e80583aSopenharmony_ci  /**
1606e80583aSopenharmony_ci   * Clear all missions in the ability manager service.
1616e80583aSopenharmony_ci   * locked mission will not clear
1626e80583aSopenharmony_ci   *
1636e80583aSopenharmony_ci   * @return nothing.
1646e80583aSopenharmony_ci   */
1656e80583aSopenharmony_ci  async clearAllMissions(): Promise<void> {
1666e80583aSopenharmony_ci    try {
1676e80583aSopenharmony_ci      await missionManager.clearAllMissions();
1686e80583aSopenharmony_ci      Log.showDebug(TAG, 'clearAllMissions success');
1696e80583aSopenharmony_ci    } catch (err) {
1706e80583aSopenharmony_ci      Log.showError(TAG, `clearAllMissions fail, err: ${JSON.stringify(err)}`);
1716e80583aSopenharmony_ci    }
1726e80583aSopenharmony_ci  }
1736e80583aSopenharmony_ci
1746e80583aSopenharmony_ci  /**
1756e80583aSopenharmony_ci   * lockMission
1766e80583aSopenharmony_ci   *
1776e80583aSopenharmony_ci   * @param missionId mission id to lock.
1786e80583aSopenharmony_ci   */
1796e80583aSopenharmony_ci  lockMission(missionId: number): void {
1806e80583aSopenharmony_ci    Log.showInfo(TAG, `lockMission start! missionId: ${missionId}`);
1816e80583aSopenharmony_ci    this.mMissionId = missionId;
1826e80583aSopenharmony_ci    this.mLockState = true;
1836e80583aSopenharmony_ci    missionManager.lockMission(missionId, this.lockCallback.bind(this));
1846e80583aSopenharmony_ci  }
1856e80583aSopenharmony_ci
1866e80583aSopenharmony_ci  /**
1876e80583aSopenharmony_ci   * unlockMission
1886e80583aSopenharmony_ci   *
1896e80583aSopenharmony_ci   * @param missionId mission id to unlock.
1906e80583aSopenharmony_ci   */
1916e80583aSopenharmony_ci  unlockMission(missionId: number): void {
1926e80583aSopenharmony_ci    Log.showInfo(TAG, `unlockMission start! missionId: ${missionId}`);
1936e80583aSopenharmony_ci    this.mMissionId = missionId;
1946e80583aSopenharmony_ci    this.mLockState = false;
1956e80583aSopenharmony_ci    missionManager.unlockMission(missionId, this.lockCallback.bind(this));
1966e80583aSopenharmony_ci  }
1976e80583aSopenharmony_ci
1986e80583aSopenharmony_ci  private async lockCallback(): Promise<void> {
1996e80583aSopenharmony_ci    Log.showDebug(TAG, 'lockCallback start');
2006e80583aSopenharmony_ci    // update mission recent card
2016e80583aSopenharmony_ci    let mRecentMissionsList = await amsMissionManager.getRecentMissionsList();
2026e80583aSopenharmony_ci    mRecentMissionsList.find(item => {
2036e80583aSopenharmony_ci      return item.missionId === this.mMissionId;
2046e80583aSopenharmony_ci    }).lockedState = this.mLockState;
2056e80583aSopenharmony_ci    if (globalThis.recentMode && windowManager.isSplitWindowMode(globalThis.recentMode)) {
2066e80583aSopenharmony_ci      mRecentMissionsList.forEach((item, index) => {
2076e80583aSopenharmony_ci        if (item.missionId == globalThis.splitMissionId) {
2086e80583aSopenharmony_ci          mRecentMissionsList.splice(index, 1);
2096e80583aSopenharmony_ci          return;
2106e80583aSopenharmony_ci        }
2116e80583aSopenharmony_ci      });
2126e80583aSopenharmony_ci    }
2136e80583aSopenharmony_ci    AppStorage.setOrCreate('recentMissionsList', mRecentMissionsList);
2146e80583aSopenharmony_ci  };
2156e80583aSopenharmony_ci
2166e80583aSopenharmony_ci  /**
2176e80583aSopenharmony_ci   * Get recent mission snapshot info
2186e80583aSopenharmony_ci   *
2196e80583aSopenharmony_ci   * @param missionId mission id to get snapshot.
2206e80583aSopenharmony_ci   * @return snapshot info
2216e80583aSopenharmony_ci   */
2226e80583aSopenharmony_ci  async getMissionSnapShot(missionId: number): Promise<SnapShotInfo> {
2236e80583aSopenharmony_ci    let snapShotInfo: SnapShotInfo = new SnapShotInfo();
2246e80583aSopenharmony_ci    Log.showInfo(TAG, `getMissionSnapShot start! missionId: ${missionId}`);
2256e80583aSopenharmony_ci    try {
2266e80583aSopenharmony_ci      let missionSnapshot: missionManager.MissionSnapshot = null;
2276e80583aSopenharmony_ci      missionSnapshot = await missionManager.getMissionSnapShot('', missionId);
2286e80583aSopenharmony_ci      Log.showInfo(TAG, 'getMissionSnapShot end');
2296e80583aSopenharmony_ci      const imageInfo = await missionSnapshot.snapshot.getImageInfo();
2306e80583aSopenharmony_ci      Log.showDebug(TAG, `getMissionSnapShot ${missionId} success ${JSON.stringify(imageInfo)}`);
2316e80583aSopenharmony_ci      snapShotInfo.missionId = missionId;
2326e80583aSopenharmony_ci      snapShotInfo.snapShotImage = missionSnapshot.snapshot;
2336e80583aSopenharmony_ci      snapShotInfo.snapShotImageWidth = imageInfo.size.width;
2346e80583aSopenharmony_ci      snapShotInfo.snapShotImageHeight = imageInfo.size.height;
2356e80583aSopenharmony_ci    } catch (err) {
2366e80583aSopenharmony_ci      Log.showError(TAG, `missionManager.getMissionSnapShot fail, missionId:${missionId} err: ${JSON.stringify(err)}`);
2376e80583aSopenharmony_ci    }
2386e80583aSopenharmony_ci    return snapShotInfo;
2396e80583aSopenharmony_ci  }
2406e80583aSopenharmony_ci
2416e80583aSopenharmony_ci  /**
2426e80583aSopenharmony_ci   * Move mission to front
2436e80583aSopenharmony_ci   *
2446e80583aSopenharmony_ci   * @param missionId
2456e80583aSopenharmony_ci   */
2466e80583aSopenharmony_ci  async moveMissionToFront(missionId: number, winMode?: number) {
2476e80583aSopenharmony_ci    Log.showInfo(TAG, `moveMissionToFront missionId:  ${missionId}`);
2486e80583aSopenharmony_ci    try {
2496e80583aSopenharmony_ci      winMode ? await missionManager.moveMissionToFront(missionId, { windowMode: winMode }):
2506e80583aSopenharmony_ci        await missionManager.moveMissionToFront(missionId);
2516e80583aSopenharmony_ci      Log.showDebug(TAG, 'moveMissionToFront missionId end success');
2526e80583aSopenharmony_ci    } catch (err) {
2536e80583aSopenharmony_ci      Log.showError(TAG, `moveMissionToFront fail, err: ${JSON.stringify(err)}`);
2546e80583aSopenharmony_ci    }
2556e80583aSopenharmony_ci  }
2566e80583aSopenharmony_ci}
2576e80583aSopenharmony_ci
2586e80583aSopenharmony_ciexport const amsMissionManager = AmsMissionManager.getInstance();