• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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 common from '@ohos.app.ability.common';
17import request from '@ohos.request';
18import promptAction from '@ohos.promptAction';
19import { logger } from '../utils/Logger';
20import { TOAST_BOTTOM, TASK_MAX } from '../utils/Constants';
21
22const TAG: string = 'RequestDownload';
23
24class RequestDownload {
25  private context: common.UIAbilityContext | undefined = undefined;
26  private waitList: Array<string[]> = [];
27  private downloadTask: request.agent.Task | undefined = undefined;
28
29  constructor() {
30    setInterval(() => {
31      this.flushBackgroundTask()
32    }, 2000);
33  }
34
35  async downloadFilesBackground(folder: string, files: Array<string>) {
36    logger.info(TAG, 'downloadFiles');
37    this.context = getContext(this) as common.UIAbilityContext;
38    files.forEach((item: string) => {
39      this.waitList.push([folder, item]);
40    });
41  }
42
43  async flushBackgroundTask() {
44    let tasks = await request.agent.search({
45      state: request.agent.State.RUNNING
46    });
47    if (tasks.length < TASK_MAX && this.waitList.length > 0) {
48      let downloadList: Array<string[]> = [];
49      if (this.waitList.length <= TASK_MAX - tasks.length) {
50        downloadList = this.waitList;
51        this.waitList = [];
52      } else {
53        downloadList = this.waitList.slice(0, TASK_MAX - tasks.length);
54        this.waitList = this.waitList.slice(TASK_MAX - tasks.length, this.waitList.length);
55      }
56      logger.info(TAG, `this.waitList = ${JSON.stringify(this.waitList)}`);
57      this.createBackgroundTask(downloadList);
58    }
59  }
60
61  async createBackgroundTask(downloadList: Array<string[]>) {
62    if (this.context === undefined) {
63      return;
64    }
65    for (let i = 0; i < downloadList.length; i++) {
66      try {
67        let splitUrl = downloadList[i][1].split('//')[1].split('/');
68        let downloadConfig: request.agent.Config = {
69          action: request.agent.Action.DOWNLOAD,
70          url: downloadList[i][1],
71          method: 'POST',
72          title: 'download',
73          mode: request.agent.Mode.BACKGROUND,
74          network: request.agent.Network.ANY,
75          saveas: `./${downloadList[i][0]}/${splitUrl[splitUrl.length-1]}`,
76          overwrite: true,
77          gauge: true
78        }
79        let downTask = await request.agent.create(this.context, downloadConfig);
80        await downTask.start();
81      } catch (err) {
82        logger.error(TAG, `task  err, err  = ${JSON.stringify(err)}`);
83        this.waitList.push(downloadList[i]);
84      }
85    }
86  }
87
88  async downloadFile(folder: string, url: string, callback: (progress: number, isSuccess: boolean) => void) {
89    logger.info(TAG, 'downloadFile');
90    // 查询到存在正在执行的下载任务,提示并返回
91    let tasks = await request.agent.search({
92      state: request.agent.State.RUNNING,
93      action: request.agent.Action.DOWNLOAD,
94      mode: request.agent.Mode.FOREGROUND
95    });
96    if (tasks.length > 0) {
97      promptAction.showToast({ message: $r('app.string.have_download_task_tips'), bottom: TOAST_BOTTOM });
98      return;
99    }
100    let splitUrl = url.split('//')[1].split('/');
101    let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
102    let downloadConfig: request.agent.Config = {
103      action: request.agent.Action.DOWNLOAD,
104      url: url,
105      method: 'POST',
106      title: 'download',
107      mode: request.agent.Mode.FOREGROUND,
108      network: request.agent.Network.ANY,
109      saveas: `./${folder}/${splitUrl[splitUrl.length-1]}`,
110      overwrite: true
111    }
112    logger.info(TAG, `downloadFile, downloadConfig = ${JSON.stringify(downloadConfig)}`);
113    try {
114      this.downloadTask = await request.agent.create(context, downloadConfig);
115      this.downloadTask.on('progress', (progress: request.agent.Progress) => {
116        logger.info(TAG, `progress,  progress = ${progress.processed} ${progress.state}`);
117        let processed = Number(progress.processed.toString()).valueOf();
118        let size = progress.sizes[0];
119        let process: number = Math.floor(processed / size * 100);
120        if (process < 100) {
121          callback(process, false);
122        }
123      })
124      this.downloadTask.on('completed', (progress: request.agent.Progress) => {
125        logger.info(TAG, `download complete, file= ${url}, progress = ${progress.processed}`);
126        callback(100, true);
127        this.deleteTask();
128      })
129      this.downloadTask.on('failed', async (progress: request.agent.Progress) => {
130        if (this.downloadTask) {
131          let taskInfo = await request.agent.show(this.downloadTask.tid);
132          logger.info(TAG, `fail,  resean = ${taskInfo.reason}, faults = ${JSON.stringify(taskInfo.faults)}`);
133        }
134        callback(100, false);
135        this.deleteTask();
136      })
137      await this.downloadTask.start();
138    } catch (err) {
139      logger.error(TAG, `task  err, err  = ${JSON.stringify(err)}`);
140      callback(100, false);
141    }
142  }
143
144  async deleteTask() {
145    if (this.downloadTask) {
146      try {
147        this.downloadTask.off('progress');
148        this.downloadTask.off('completed');
149        this.downloadTask.off('failed');
150        await request.agent.remove(this.downloadTask.tid);
151      } catch (err) {
152        logger.info(TAG, `deleteTask fail, err= ${JSON.stringify(err)}`);
153      }
154    }
155
156    this.downloadTask = undefined;
157  }
158}
159
160export const requestDownload = new RequestDownload();