19b19030aSopenharmony_ci/*
29b19030aSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
39b19030aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49b19030aSopenharmony_ci * you may not use this file except in compliance with the License.
59b19030aSopenharmony_ci * You may obtain a copy of the License at
69b19030aSopenharmony_ci *
79b19030aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89b19030aSopenharmony_ci *
99b19030aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109b19030aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119b19030aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129b19030aSopenharmony_ci * See the License for the specific language governing permissions and
139b19030aSopenharmony_ci * limitations under the License.
149b19030aSopenharmony_ci */
159b19030aSopenharmony_ci
169b19030aSopenharmony_ciimport type common from '@ohos.app.ability.common';
179b19030aSopenharmony_ciimport update from '@ohos.update';
189b19030aSopenharmony_ciimport { PACKAGE_NAME, UpdateState, UpgradeCallResult, } from '../const/update_const';
199b19030aSopenharmony_ciimport type { BusinessError, OtaStatus, UpgradeData} from '../const/update_const';
209b19030aSopenharmony_ciimport { LogUtils } from '../util/LogUtils';
219b19030aSopenharmony_ciimport { UpdateUtils } from '../util/UpdateUtils';
229b19030aSopenharmony_ci
239b19030aSopenharmony_ci/**
249b19030aSopenharmony_ci * 方法超时控制装饰器
259b19030aSopenharmony_ci *
269b19030aSopenharmony_ci * @param timeout 超时事件ms
279b19030aSopenharmony_ci */
289b19030aSopenharmony_ciexport function enableTimeOutCheck<T>(timeout?: number): MethodDecorator {
299b19030aSopenharmony_ci  const TIME = 30000;
309b19030aSopenharmony_ci  let realTimeout: number = timeout ?? TIME;
319b19030aSopenharmony_ci  return function inner(target: Object, propertyKey: string, descriptor: PropertyDescriptor): void {
329b19030aSopenharmony_ci    const original = descriptor.value;
339b19030aSopenharmony_ci    descriptor.value = function (...args): Promise<unknown> {
349b19030aSopenharmony_ci      return new Promise((resolve, reject) => {
359b19030aSopenharmony_ci        let upgradeData: UpgradeData<T> = {
369b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
379b19030aSopenharmony_ci        };
389b19030aSopenharmony_ci        const requestTimeout = setTimeout(() => {
399b19030aSopenharmony_ci          upgradeData.callResult = UpgradeCallResult.TIME_OUT;
409b19030aSopenharmony_ci          resolve(upgradeData);
419b19030aSopenharmony_ci        }, realTimeout);
429b19030aSopenharmony_ci        let result: Promise<T>;
439b19030aSopenharmony_ci        try {
449b19030aSopenharmony_ci          result = original.call(this, ...args);
459b19030aSopenharmony_ci        } catch (error) {
469b19030aSopenharmony_ci          LogUtils.error('UpdateManager', 'error: ' + JSON.stringify(error));
479b19030aSopenharmony_ci          result = null;
489b19030aSopenharmony_ci        }
499b19030aSopenharmony_ci        if (!result) {
509b19030aSopenharmony_ci          clearTimeout(requestTimeout);
519b19030aSopenharmony_ci          upgradeData.callResult = UpgradeCallResult.ERROR;
529b19030aSopenharmony_ci          resolve(upgradeData); // 不处理错误
539b19030aSopenharmony_ci          return;
549b19030aSopenharmony_ci        }
559b19030aSopenharmony_ci        result.then(innerRes => {
569b19030aSopenharmony_ci          clearTimeout(requestTimeout);
579b19030aSopenharmony_ci          resolve(innerRes);
589b19030aSopenharmony_ci        }).catch(err => {
599b19030aSopenharmony_ci          LogUtils.error('UpdateManager', 'err: ' + JSON.stringify(err));
609b19030aSopenharmony_ci          clearTimeout(requestTimeout);
619b19030aSopenharmony_ci          upgradeData.callResult = UpgradeCallResult.ERROR;
629b19030aSopenharmony_ci          upgradeData.error = err;
639b19030aSopenharmony_ci          resolve(upgradeData); // 不处理错误
649b19030aSopenharmony_ci        });
659b19030aSopenharmony_ci      });
669b19030aSopenharmony_ci    };
679b19030aSopenharmony_ci  };
689b19030aSopenharmony_ci}
699b19030aSopenharmony_ci
709b19030aSopenharmony_ciexport interface IUpdate {
719b19030aSopenharmony_ci  bind(subType: number, callback : Function): void;
729b19030aSopenharmony_ci  getOtaStatus(): Promise<UpgradeData<OtaStatus>>;
739b19030aSopenharmony_ci  getNewVersion(): Promise<UpgradeData<update.NewVersionInfo>>;
749b19030aSopenharmony_ci  getNewVersionDescription(descVersionDigest: string, descFormat: update.DescriptionFormat,
759b19030aSopenharmony_ci    descLanguage: string): Promise<UpgradeData<Array<update.ComponentDescription>>>;
769b19030aSopenharmony_ci  getCurrentVersionDescription(descFormat: update.DescriptionFormat,
779b19030aSopenharmony_ci    descLanguage: string): Promise<UpgradeData<Array<update.ComponentDescription>>>;
789b19030aSopenharmony_ci  checkNewVersion(): Promise<UpgradeData<update.CheckResult>>;
799b19030aSopenharmony_ci  upgrade(upgradeVersionDigest: string, upgradeOrder: number): Promise<void>;
809b19030aSopenharmony_ci  download(downloadVersionDigest: string, downloadNetwork: number, downloadOrder: number): Promise<void>;
819b19030aSopenharmony_ci  cancel(): void;
829b19030aSopenharmony_ci  getCurrentVersionInfo(): Promise<UpgradeData<update.CurrentVersionInfo>>;
839b19030aSopenharmony_ci}
849b19030aSopenharmony_ci
859b19030aSopenharmony_ci/**
869b19030aSopenharmony_ci * 升级接口管理类
879b19030aSopenharmony_ci *
889b19030aSopenharmony_ci * @since 2022-06-05
899b19030aSopenharmony_ci */
909b19030aSopenharmony_ciexport class UpdateManager implements IUpdate {
919b19030aSopenharmony_ci  private otaUpdater: update.Updater;
929b19030aSopenharmony_ci
939b19030aSopenharmony_ci  public constructor() {
949b19030aSopenharmony_ci  }
959b19030aSopenharmony_ci
969b19030aSopenharmony_ci  /**
979b19030aSopenharmony_ci   * 绑定DUE
989b19030aSopenharmony_ci   *
999b19030aSopenharmony_ci   * @param subType 升级类型
1009b19030aSopenharmony_ci   * @param callback 回调
1019b19030aSopenharmony_ci   */
1029b19030aSopenharmony_ci  bind(subType: number, callback: update.UpgradeTaskCallback): void {
1039b19030aSopenharmony_ci    let upgradeInfo: update.UpgradeInfo = {
1049b19030aSopenharmony_ci      upgradeApp: PACKAGE_NAME,
1059b19030aSopenharmony_ci      businessType: {
1069b19030aSopenharmony_ci        vendor: update.BusinessVendor.PUBLIC,
1079b19030aSopenharmony_ci        subType: subType
1089b19030aSopenharmony_ci      }
1099b19030aSopenharmony_ci    };
1109b19030aSopenharmony_ci
1119b19030aSopenharmony_ci    try {
1129b19030aSopenharmony_ci      this.otaUpdater = update.getOnlineUpdater(upgradeInfo);
1139b19030aSopenharmony_ci      let eventClassifyInfo: update.EventClassifyInfo = { eventClassify: 0x01000000, extraInfo: '' };
1149b19030aSopenharmony_ci      this.otaUpdater?.on(eventClassifyInfo, callback);
1159b19030aSopenharmony_ci    } catch (error) {
1169b19030aSopenharmony_ci      LogUtils.error('UpdateManager', 'otaUpdater init fail ' + JSON.stringify(error));
1179b19030aSopenharmony_ci    }
1189b19030aSopenharmony_ci  }
1199b19030aSopenharmony_ci
1209b19030aSopenharmony_ci  /**
1219b19030aSopenharmony_ci   * 取升级状态
1229b19030aSopenharmony_ci   *
1239b19030aSopenharmony_ci   * @return resolve 状态/reject 错误信息
1249b19030aSopenharmony_ci   */
1259b19030aSopenharmony_ci  @enableTimeOutCheck()
1269b19030aSopenharmony_ci  async getOtaStatus(): Promise<UpgradeData<OtaStatus>> {
1279b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
1289b19030aSopenharmony_ci      this.otaUpdater?.getTaskInfo().then((result: update.TaskInfo) => {
1299b19030aSopenharmony_ci        this.log(`getOtaStatus result is ${JSON.stringify(result)}`);
1309b19030aSopenharmony_ci        let upgradeData: UpgradeData<OtaStatus> = {
1319b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK
1329b19030aSopenharmony_ci        };
1339b19030aSopenharmony_ci        let taskStatus = result?.existTask ? result?.taskBody?.status : UpdateState.INIT;
1349b19030aSopenharmony_ci        let otaStatus: OtaStatus = {
1359b19030aSopenharmony_ci          status: taskStatus,
1369b19030aSopenharmony_ci          percent: result?.taskBody?.progress ?? 0,
1379b19030aSopenharmony_ci          endReason: result?.taskBody?.errorMessages?.[0]?.errorCode?.toString()
1389b19030aSopenharmony_ci        };
1399b19030aSopenharmony_ci        upgradeData.data = otaStatus;
1409b19030aSopenharmony_ci        resolve(upgradeData);
1419b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
1429b19030aSopenharmony_ci        this.logError(`getOtaStatus error is ${JSON.stringify(err)}`);
1439b19030aSopenharmony_ci        let upgradeData: UpgradeData<OtaStatus> = {
1449b19030aSopenharmony_ci          callResult: UpgradeCallResult.ERROR,
1459b19030aSopenharmony_ci          error: err
1469b19030aSopenharmony_ci        };
1479b19030aSopenharmony_ci        resolve(upgradeData);
1489b19030aSopenharmony_ci      });
1499b19030aSopenharmony_ci    });
1509b19030aSopenharmony_ci  }
1519b19030aSopenharmony_ci
1529b19030aSopenharmony_ci  /**
1539b19030aSopenharmony_ci   * 从due数据库取新版本信息
1549b19030aSopenharmony_ci   *
1559b19030aSopenharmony_ci   * @return resolve 新版本信息/reject 错误信息
1569b19030aSopenharmony_ci   */
1579b19030aSopenharmony_ci  @enableTimeOutCheck()
1589b19030aSopenharmony_ci  async getNewVersion(): Promise<UpgradeData<update.NewVersionInfo>> {
1599b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
1609b19030aSopenharmony_ci      this.otaUpdater?.getNewVersionInfo().then((result: update.NewVersionInfo) => {
1619b19030aSopenharmony_ci        this.log('getNewVersion result:' + JSON.stringify(result));
1629b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.NewVersionInfo> = {
1639b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
1649b19030aSopenharmony_ci          data: result
1659b19030aSopenharmony_ci        };
1669b19030aSopenharmony_ci        resolve(upgradeData);
1679b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
1689b19030aSopenharmony_ci        this.logError('getNewVersion result:' + JSON.stringify(err));
1699b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.NewVersionInfo> = {
1709b19030aSopenharmony_ci          callResult: UpgradeCallResult.ERROR,
1719b19030aSopenharmony_ci          error: err
1729b19030aSopenharmony_ci        };
1739b19030aSopenharmony_ci        resolve(upgradeData);
1749b19030aSopenharmony_ci      });
1759b19030aSopenharmony_ci    });
1769b19030aSopenharmony_ci  }
1779b19030aSopenharmony_ci
1789b19030aSopenharmony_ci  /**
1799b19030aSopenharmony_ci   * 获取新版本描述文件
1809b19030aSopenharmony_ci   *
1819b19030aSopenharmony_ci   * @param descVersionDigest 版本摘要
1829b19030aSopenharmony_ci   * @param descFormat 描述文件格式
1839b19030aSopenharmony_ci   * @param descLanguage 描述文件语言
1849b19030aSopenharmony_ci   * @return 新版本描述文件
1859b19030aSopenharmony_ci   */
1869b19030aSopenharmony_ci  @enableTimeOutCheck()
1879b19030aSopenharmony_ci  async getNewVersionDescription(descVersionDigest: string, descFormat: update.DescriptionFormat,
1889b19030aSopenharmony_ci    descLanguage: string): Promise<UpgradeData<Array<update.ComponentDescription>>> {
1899b19030aSopenharmony_ci    let versionDigestInfo: update.VersionDigestInfo = {
1909b19030aSopenharmony_ci      versionDigest: descVersionDigest, // 检测结果中的版本摘要信息
1919b19030aSopenharmony_ci    };
1929b19030aSopenharmony_ci    let descriptionOptions: update.DescriptionOptions = {
1939b19030aSopenharmony_ci      format: descFormat,
1949b19030aSopenharmony_ci      language: descLanguage
1959b19030aSopenharmony_ci    };
1969b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
1979b19030aSopenharmony_ci      this.otaUpdater?.getNewVersionDescription(versionDigestInfo,
1989b19030aSopenharmony_ci        descriptionOptions).then((result: Array<update.ComponentDescription>) => {
1999b19030aSopenharmony_ci        this.log('getNewVersionDescription result:' + JSON.stringify(result));
2009b19030aSopenharmony_ci        let upgradeData: UpgradeData<Array<update.ComponentDescription>> = {
2019b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
2029b19030aSopenharmony_ci          data: result
2039b19030aSopenharmony_ci        };
2049b19030aSopenharmony_ci        resolve(upgradeData);
2059b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
2069b19030aSopenharmony_ci        this.logError('getNewVersionDescription err:' + JSON.stringify(err));
2079b19030aSopenharmony_ci        let upgradeData: UpgradeData<Array<update.ComponentDescription>> = {
2089b19030aSopenharmony_ci          callResult: UpgradeCallResult.ERROR,
2099b19030aSopenharmony_ci          error: err
2109b19030aSopenharmony_ci        };
2119b19030aSopenharmony_ci        resolve(upgradeData);
2129b19030aSopenharmony_ci      });
2139b19030aSopenharmony_ci    });
2149b19030aSopenharmony_ci  }
2159b19030aSopenharmony_ci
2169b19030aSopenharmony_ci  /**
2179b19030aSopenharmony_ci   * 获取当前版本升级日志
2189b19030aSopenharmony_ci   *
2199b19030aSopenharmony_ci   * @param descFormat 描述文件格式
2209b19030aSopenharmony_ci   * @param descLanguage 描述文件语言
2219b19030aSopenharmony_ci   * @return 当前版本描述文件
2229b19030aSopenharmony_ci   */
2239b19030aSopenharmony_ci  @enableTimeOutCheck()
2249b19030aSopenharmony_ci  async getCurrentVersionDescription(descFormat: update.DescriptionFormat,
2259b19030aSopenharmony_ci    descLanguage: string): Promise<UpgradeData<Array<update.ComponentDescription>>> {
2269b19030aSopenharmony_ci    let options: update.DescriptionOptions = {
2279b19030aSopenharmony_ci      format: descFormat,
2289b19030aSopenharmony_ci      language: descLanguage
2299b19030aSopenharmony_ci    };
2309b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
2319b19030aSopenharmony_ci      this.otaUpdater?.getCurrentVersionDescription(options, (err, result) => {
2329b19030aSopenharmony_ci        this.log('getCurrentVersionDescription result:' + JSON.stringify(result));
2339b19030aSopenharmony_ci        let upgradeData: UpgradeData<Array<update.ComponentDescription>> = {
2349b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
2359b19030aSopenharmony_ci          data: result,
2369b19030aSopenharmony_ci          error: {
2379b19030aSopenharmony_ci            data: [{ errorCode: err?.data?.[0]?.errorCode }]
2389b19030aSopenharmony_ci          }
2399b19030aSopenharmony_ci        };
2409b19030aSopenharmony_ci        if (!UpdateUtils.isSuccessCallback(result, err)) {
2419b19030aSopenharmony_ci          this.logError('getCurrentVersionDescription error is ${JSON.stringify(err)}');
2429b19030aSopenharmony_ci          upgradeData.callResult = UpgradeCallResult.ERROR;
2439b19030aSopenharmony_ci        }
2449b19030aSopenharmony_ci        resolve(upgradeData);
2459b19030aSopenharmony_ci      });
2469b19030aSopenharmony_ci    });
2479b19030aSopenharmony_ci  }
2489b19030aSopenharmony_ci
2499b19030aSopenharmony_ci  /**
2509b19030aSopenharmony_ci   * 从服务器取搜索新版本
2519b19030aSopenharmony_ci   *
2529b19030aSopenharmony_ci   * @return resolve 新版本信息/reject 错误信息
2539b19030aSopenharmony_ci   */
2549b19030aSopenharmony_ci  @enableTimeOutCheck()
2559b19030aSopenharmony_ci  async checkNewVersion(): Promise<UpgradeData<update.CheckResult>> {
2569b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
2579b19030aSopenharmony_ci      this.otaUpdater?.checkNewVersion().then((result: update.CheckResult) => {
2589b19030aSopenharmony_ci        this.log('checkNewVersion result:' + JSON.stringify(result));
2599b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.CheckResult> = {
2609b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
2619b19030aSopenharmony_ci          data: result,
2629b19030aSopenharmony_ci        };
2639b19030aSopenharmony_ci        if (!result?.isExistNewVersion || !result?.newVersionInfo) {
2649b19030aSopenharmony_ci          upgradeData.callResult = UpgradeCallResult.ERROR;
2659b19030aSopenharmony_ci        }
2669b19030aSopenharmony_ci        resolve(upgradeData);
2679b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
2689b19030aSopenharmony_ci        this.logError('checkNewVersion err:' + JSON.stringify(err));
2699b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.CheckResult> = {
2709b19030aSopenharmony_ci          callResult: UpgradeCallResult.ERROR,
2719b19030aSopenharmony_ci          error: err
2729b19030aSopenharmony_ci        };
2739b19030aSopenharmony_ci        resolve(upgradeData);
2749b19030aSopenharmony_ci      });
2759b19030aSopenharmony_ci    });
2769b19030aSopenharmony_ci  }
2779b19030aSopenharmony_ci
2789b19030aSopenharmony_ci  /**
2799b19030aSopenharmony_ci   * 升级
2809b19030aSopenharmony_ci   *
2819b19030aSopenharmony_ci   * @param upgradeVersionDigest 版本摘要
2829b19030aSopenharmony_ci   * @param upgradeOrder 升级命令
2839b19030aSopenharmony_ci   * @return 调用结果
2849b19030aSopenharmony_ci   */
2859b19030aSopenharmony_ci  upgrade(upgradeVersionDigest: string, upgradeOrder: number): Promise<void> {
2869b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
2879b19030aSopenharmony_ci      let versionDigestInfo: update.VersionDigestInfo = {
2889b19030aSopenharmony_ci        versionDigest: upgradeVersionDigest
2899b19030aSopenharmony_ci      };
2909b19030aSopenharmony_ci      let upgradeOptions: update.UpgradeOptions = {
2919b19030aSopenharmony_ci        order: upgradeOrder
2929b19030aSopenharmony_ci      };
2939b19030aSopenharmony_ci      this.otaUpdater?.upgrade(versionDigestInfo, upgradeOptions).then(() => {
2949b19030aSopenharmony_ci        resolve();
2959b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
2969b19030aSopenharmony_ci        this.logError('upgrade err:' + JSON.stringify(err));
2979b19030aSopenharmony_ci        reject(err);
2989b19030aSopenharmony_ci      });
2999b19030aSopenharmony_ci    });
3009b19030aSopenharmony_ci  }
3019b19030aSopenharmony_ci
3029b19030aSopenharmony_ci  /**
3039b19030aSopenharmony_ci   * 下载
3049b19030aSopenharmony_ci   *
3059b19030aSopenharmony_ci   * @param upgradeVersionDigest 版本摘要
3069b19030aSopenharmony_ci   * @param downloadNetwork 下载网络
3079b19030aSopenharmony_ci   * @param upgradeOrder 下载命令
3089b19030aSopenharmony_ci   * @return 调用结果
3099b19030aSopenharmony_ci   */
3109b19030aSopenharmony_ci  download(downloadVersionDigest: string, downloadNetwork: number, downloadOrder: number): Promise<void> {
3119b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
3129b19030aSopenharmony_ci      let versionDigestInfo: update.VersionDigestInfo = {
3139b19030aSopenharmony_ci        versionDigest: downloadVersionDigest
3149b19030aSopenharmony_ci      };
3159b19030aSopenharmony_ci      let downloadOptions: update.DownloadOptions = {
3169b19030aSopenharmony_ci        allowNetwork: downloadNetwork,
3179b19030aSopenharmony_ci        order: downloadOrder
3189b19030aSopenharmony_ci      };
3199b19030aSopenharmony_ci      this.otaUpdater?.download(versionDigestInfo, downloadOptions).then(() => {
3209b19030aSopenharmony_ci        this.log('download succeeded.');
3219b19030aSopenharmony_ci        resolve();
3229b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
3239b19030aSopenharmony_ci        this.logError('download err:' + JSON.stringify(err));
3249b19030aSopenharmony_ci        reject(err);
3259b19030aSopenharmony_ci      });
3269b19030aSopenharmony_ci    });
3279b19030aSopenharmony_ci  }
3289b19030aSopenharmony_ci
3299b19030aSopenharmony_ci  /**
3309b19030aSopenharmony_ci   * 继续下载
3319b19030aSopenharmony_ci   *
3329b19030aSopenharmony_ci   * @param upgradeVersionDigest 版本摘要
3339b19030aSopenharmony_ci   * @param downloadNetwork 下载网络
3349b19030aSopenharmony_ci   * @return 调用结果
3359b19030aSopenharmony_ci   */
3369b19030aSopenharmony_ci  resumeDownload(downloadVersionDigest: string, downloadNetwork: number): Promise<void> {
3379b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
3389b19030aSopenharmony_ci      let versionDigestInfo: update.VersionDigestInfo = {
3399b19030aSopenharmony_ci        versionDigest: downloadVersionDigest
3409b19030aSopenharmony_ci      };
3419b19030aSopenharmony_ci
3429b19030aSopenharmony_ci      let resumeDownloadOptions: update.ResumeDownloadOptions = {
3439b19030aSopenharmony_ci        allowNetwork: downloadNetwork
3449b19030aSopenharmony_ci      };
3459b19030aSopenharmony_ci      this.otaUpdater?.resumeDownload(versionDigestInfo, resumeDownloadOptions).then(() => {
3469b19030aSopenharmony_ci        this.log('download succeeded.');
3479b19030aSopenharmony_ci        resolve();
3489b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
3499b19030aSopenharmony_ci        this.logError('resumeDownload err:' + JSON.stringify(err));
3509b19030aSopenharmony_ci        reject(err);
3519b19030aSopenharmony_ci      });
3529b19030aSopenharmony_ci    });
3539b19030aSopenharmony_ci  }
3549b19030aSopenharmony_ci
3559b19030aSopenharmony_ci  /**
3569b19030aSopenharmony_ci   * 取消升级
3579b19030aSopenharmony_ci   */
3589b19030aSopenharmony_ci  cancel(): void {
3599b19030aSopenharmony_ci    (<any> this.otaUpdater).cancel();
3609b19030aSopenharmony_ci  }
3619b19030aSopenharmony_ci
3629b19030aSopenharmony_ci  /**
3639b19030aSopenharmony_ci   * 取当前版本数据
3649b19030aSopenharmony_ci   *
3659b19030aSopenharmony_ci   * @return resolve 当前版本信息/reject 错误信息
3669b19030aSopenharmony_ci   */
3679b19030aSopenharmony_ci  @enableTimeOutCheck()
3689b19030aSopenharmony_ci  async getCurrentVersionInfo(): Promise<UpgradeData<update.CurrentVersionInfo>> {
3699b19030aSopenharmony_ci    return new Promise((resolve, reject) => {
3709b19030aSopenharmony_ci      this.otaUpdater?.getCurrentVersionInfo().then((result: update.CurrentVersionInfo) => {
3719b19030aSopenharmony_ci        this.log('getCurrentVersionInfo result:' + JSON.stringify(result));
3729b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.CurrentVersionInfo> = {
3739b19030aSopenharmony_ci          callResult: UpgradeCallResult.OK,
3749b19030aSopenharmony_ci          data: result
3759b19030aSopenharmony_ci        };
3769b19030aSopenharmony_ci        resolve(upgradeData);
3779b19030aSopenharmony_ci      }).catch((err: BusinessError) => {
3789b19030aSopenharmony_ci        this.logError('getCurrentVersionInfo err:' + JSON.stringify(err));
3799b19030aSopenharmony_ci        let upgradeData: UpgradeData<update.CurrentVersionInfo> = {
3809b19030aSopenharmony_ci          callResult: UpgradeCallResult.ERROR,
3819b19030aSopenharmony_ci          error: err
3829b19030aSopenharmony_ci        };
3839b19030aSopenharmony_ci        resolve(upgradeData);
3849b19030aSopenharmony_ci      });
3859b19030aSopenharmony_ci    });
3869b19030aSopenharmony_ci  }
3879b19030aSopenharmony_ci
3889b19030aSopenharmony_ci  private log(message: string): void {
3899b19030aSopenharmony_ci    LogUtils.log('UpdateManager', message);
3909b19030aSopenharmony_ci  }
3919b19030aSopenharmony_ci
3929b19030aSopenharmony_ci  private logError(message: string): void {
3939b19030aSopenharmony_ci    LogUtils.error('UpdateManager', message);
3949b19030aSopenharmony_ci  }
3959b19030aSopenharmony_ci}
3969b19030aSopenharmony_ci
3979b19030aSopenharmony_ci/**
3989b19030aSopenharmony_ci * OtaStatus缓存/数据处理
3999b19030aSopenharmony_ci *
4009b19030aSopenharmony_ci * @since 2022-07-30
4019b19030aSopenharmony_ci */
4029b19030aSopenharmony_ciexport class OtaStatusHolder {
4039b19030aSopenharmony_ci  private lastStatusHolder: StatusHolder;
4049b19030aSopenharmony_ci
4059b19030aSopenharmony_ci  /**
4069b19030aSopenharmony_ci   * 比较otaStatus与lastStatusHolder,并刷新lastStatusHolder
4079b19030aSopenharmony_ci   *
4089b19030aSopenharmony_ci   * @param otaStatus otaStatus
4099b19030aSopenharmony_ci   * @return otaStatus是否是重复事件
4109b19030aSopenharmony_ci   */
4119b19030aSopenharmony_ci  isStatusChangedAndRefresh(otaStatus: OtaStatus, eventId?: update.EventId): boolean {
4129b19030aSopenharmony_ci    const STATUS_ALIVE_TIME = 1000;
4139b19030aSopenharmony_ci    const newStatus = this.makeStatusHolder(otaStatus, eventId);
4149b19030aSopenharmony_ci    let isChanged: boolean;
4159b19030aSopenharmony_ci
4169b19030aSopenharmony_ci    if (this.lastStatusHolder != null &&
4179b19030aSopenharmony_ci    (newStatus.initTime - this.lastStatusHolder.initTime) < STATUS_ALIVE_TIME &&
4189b19030aSopenharmony_ci      newStatus.status === this.lastStatusHolder.status) {
4199b19030aSopenharmony_ci      isChanged = false;
4209b19030aSopenharmony_ci    } else {
4219b19030aSopenharmony_ci      isChanged = true;
4229b19030aSopenharmony_ci    }
4239b19030aSopenharmony_ci    this.lastStatusHolder = newStatus;
4249b19030aSopenharmony_ci    return isChanged;
4259b19030aSopenharmony_ci  }
4269b19030aSopenharmony_ci
4279b19030aSopenharmony_ci  /**
4289b19030aSopenharmony_ci   * 序列化otaStatus,保存在StatusHolder
4299b19030aSopenharmony_ci   *
4309b19030aSopenharmony_ci   * @param otaStatus
4319b19030aSopenharmony_ci   * @param isCompareProgress 是否考虑进度标志位
4329b19030aSopenharmony_ci   */
4339b19030aSopenharmony_ci  private makeStatusHolder(otaStatus: OtaStatus, eventId?: update.EventId): StatusHolder {
4349b19030aSopenharmony_ci    let otaStatusHolder: StatusHolder = { status: '', initTime: new Date().getTime() };
4359b19030aSopenharmony_ci    if (otaStatus.status == null) {
4369b19030aSopenharmony_ci      otaStatusHolder.status = '_';
4379b19030aSopenharmony_ci    } else {
4389b19030aSopenharmony_ci      otaStatusHolder.status = otaStatus.status + '_';
4399b19030aSopenharmony_ci    }
4409b19030aSopenharmony_ci    let status: number = otaStatus.status;
4419b19030aSopenharmony_ci    let isCompareStatusProgress: boolean = this.isCompareStatusProgress(status);
4429b19030aSopenharmony_ci    if (otaStatus.percent == null || !isCompareStatusProgress) {
4439b19030aSopenharmony_ci      otaStatusHolder.status += '_';
4449b19030aSopenharmony_ci    } else {
4459b19030aSopenharmony_ci      otaStatusHolder.status += otaStatus.percent + '_';
4469b19030aSopenharmony_ci    }
4479b19030aSopenharmony_ci    otaStatusHolder.status += otaStatus.endReason;
4489b19030aSopenharmony_ci    otaStatusHolder.status += eventId;
4499b19030aSopenharmony_ci
4509b19030aSopenharmony_ci    return otaStatusHolder;
4519b19030aSopenharmony_ci  }
4529b19030aSopenharmony_ci
4539b19030aSopenharmony_ci  private isCompareStatusProgress(status: number): boolean {
4549b19030aSopenharmony_ci    return status === UpdateState.DOWNLOADING || status === UpdateState.INSTALLING;
4559b19030aSopenharmony_ci  }
4569b19030aSopenharmony_ci}
4579b19030aSopenharmony_ci
4589b19030aSopenharmony_ci/**
4599b19030aSopenharmony_ci * 保存每次ota_status的信息
4609b19030aSopenharmony_ci *
4619b19030aSopenharmony_ci * @since 2022-07-18
4629b19030aSopenharmony_ci */
4639b19030aSopenharmony_ciexport interface StatusHolder {
4649b19030aSopenharmony_ci  /**
4659b19030aSopenharmony_ci   * 序列化后的status
4669b19030aSopenharmony_ci   */
4679b19030aSopenharmony_ci  status: string;
4689b19030aSopenharmony_ci
4699b19030aSopenharmony_ci  /**
4709b19030aSopenharmony_ci   * status接收的时间,ms
4719b19030aSopenharmony_ci   */
4729b19030aSopenharmony_ci  initTime: number;
4739b19030aSopenharmony_ci}
4749b19030aSopenharmony_ci
4759b19030aSopenharmony_ci/**
4769b19030aSopenharmony_ci * 信息
4779b19030aSopenharmony_ci *
4789b19030aSopenharmony_ci * @since 2022-10-25
4799b19030aSopenharmony_ci */
4809b19030aSopenharmony_ciexport interface Message {
4819b19030aSopenharmony_ci  /**
4829b19030aSopenharmony_ci   * 上下文
4839b19030aSopenharmony_ci   */
4849b19030aSopenharmony_ci  context: common.Context;
4859b19030aSopenharmony_ci
4869b19030aSopenharmony_ci  /**
4879b19030aSopenharmony_ci   * 事件
4889b19030aSopenharmony_ci   */
4899b19030aSopenharmony_ci  eventInfo: update.EventInfo;
4909b19030aSopenharmony_ci}
4919b19030aSopenharmony_ci
4929b19030aSopenharmony_ci/**
4939b19030aSopenharmony_ci * 通知的消息队列
4949b19030aSopenharmony_ci *
4959b19030aSopenharmony_ci * @since 2022-08-01
4969b19030aSopenharmony_ci */
4979b19030aSopenharmony_ciexport class MessageQueue {
4989b19030aSopenharmony_ci  private queue: Array<Message>;
4999b19030aSopenharmony_ci  private handleMessage: (context: common.Context, eventInfo: update.EventInfo) => Promise<void>;
5009b19030aSopenharmony_ci
5019b19030aSopenharmony_ci  constructor(handleMessage: (context: common.Context, eventInfo: update.EventInfo) => Promise<void>) {
5029b19030aSopenharmony_ci    this.queue = new Array<Message>();
5039b19030aSopenharmony_ci    this.handleMessage = handleMessage;
5049b19030aSopenharmony_ci  }
5059b19030aSopenharmony_ci
5069b19030aSopenharmony_ci  async execute(message: Message): Promise<void> {
5079b19030aSopenharmony_ci    if (!message) {
5089b19030aSopenharmony_ci      return;
5099b19030aSopenharmony_ci    }
5109b19030aSopenharmony_ci    this.offer(message);
5119b19030aSopenharmony_ci    if (this.queue.length === 1) {
5129b19030aSopenharmony_ci      await this.loop();
5139b19030aSopenharmony_ci    }
5149b19030aSopenharmony_ci  }
5159b19030aSopenharmony_ci
5169b19030aSopenharmony_ci  isEmpty(): boolean {
5179b19030aSopenharmony_ci    return this.queue?.length === 0;
5189b19030aSopenharmony_ci  }
5199b19030aSopenharmony_ci
5209b19030aSopenharmony_ci  private async loop(): Promise<void> {
5219b19030aSopenharmony_ci    let message: Message = this.peek();
5229b19030aSopenharmony_ci    if (message) {
5239b19030aSopenharmony_ci      await this.handleMessage?.(message.context, message.eventInfo).catch(err => {
5249b19030aSopenharmony_ci        LogUtils.error('MessageQueue', 'loop err:' + JSON.stringify(err));
5259b19030aSopenharmony_ci      });
5269b19030aSopenharmony_ci      this.poll();
5279b19030aSopenharmony_ci      await this.loop();
5289b19030aSopenharmony_ci    }
5299b19030aSopenharmony_ci  }
5309b19030aSopenharmony_ci
5319b19030aSopenharmony_ci  private offer(message: Message): void {
5329b19030aSopenharmony_ci    if (!message) {
5339b19030aSopenharmony_ci      return;
5349b19030aSopenharmony_ci    }
5359b19030aSopenharmony_ci    this.queue.push(message);
5369b19030aSopenharmony_ci  }
5379b19030aSopenharmony_ci
5389b19030aSopenharmony_ci  private poll(): void {
5399b19030aSopenharmony_ci    if (this.queue.length !== 0) {
5409b19030aSopenharmony_ci      this.queue.shift();
5419b19030aSopenharmony_ci    }
5429b19030aSopenharmony_ci  }
5439b19030aSopenharmony_ci
5449b19030aSopenharmony_ci  private peek(): Message {
5459b19030aSopenharmony_ci    if (this.queue.length !== 0) {
5469b19030aSopenharmony_ci      return this.queue[0];
5479b19030aSopenharmony_ci    }
5489b19030aSopenharmony_ci    return null;
5499b19030aSopenharmony_ci  }
5509b19030aSopenharmony_ci}