• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 MediaLib from '@ohos.multimedia.mediaLibrary';
17import { MediaConstants } from '../constants/MediaConstants';
18import { Log } from '../utils/Log';
19import { MenuContext } from './MenuContext';
20import { ProcessMenuOperation, FindSameOperation } from './ProcessMenuOperation';
21import { BroadcastConstants } from '../constants/BroadcastConstants';
22import mediaModel from '../model/MediaModel';
23import { MediaOperationType } from '../data/MediaOperationType';
24import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils';
25import { ItemDataSource } from '../vm/ItemDataSource';
26import { MediaDataItem } from '../data/MediaDataItem';
27import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem';
28
29const TAG = "CopyMenuOperation"
30
31export class CopyMenuOperation extends ProcessMenuOperation {
32    private albumInfo: SimpleAlbumDataItem;
33
34    constructor(menuContext: MenuContext) {
35        super(menuContext);
36        this.albumInfo = menuContext.albumInfo;
37    }
38
39    doAction(): void {
40        Log.info(TAG, 'copy doAction');
41        if (this.menuContext == null) {
42            Log.warn(TAG, 'menuContext is null, return');
43            return;
44        }
45
46        let dataSource: ItemDataSource = this.menuContext.dataSource;
47        if (dataSource == null) {
48            this.count = this.menuContext.items.length;
49        } else {
50            this.count = dataSource.getSelectedCount();
51        }
52        if (this.count <= 0) {
53            Log.warn(TAG, 'count <= 0, return');
54            return;
55        }
56
57        this.onOperationEnd = this.menuContext.onOperationEnd;
58        let onOperationStart = this.menuContext.onOperationStart;
59
60        onOperationStart && onOperationStart();
61
62        if (this.menuContext.deviceId) {
63            this.menuContext.broadCast.emit(BroadcastConstants.SHOW_PROGRESS_DIALOG,
64                [$r('app.string.download_progress_message'),
65                MediaOperationType.Copy, this.cancelFunc.bind(this)]);
66        } else {
67            this.menuContext.broadCast.emit(BroadcastConstants.SHOW_PROGRESS_DIALOG,
68                [$r('app.string.copy_progress_message', this.albumInfo.displayName),
69                MediaOperationType.Copy, this.cancelFunc.bind(this)]);
70        }
71
72        if (dataSource == null) {
73            this.items = this.menuContext.items;
74        } else {
75            this.items = dataSource.getSelectedItems();
76        }
77        this.processOperation();
78    }
79
80    requestOneBatchOperation() {
81        let item = this.items[this.currentBatch++] as MediaDataItem;
82        this.copyOne(item);
83    }
84
85    private async copyOne(item: MediaDataItem) {
86        if (this.menuContext.deviceId) {
87            let path = await mediaModel.getPublicDirectory(MediaLib.DirectoryType.DIR_CAMERA) + MediaConstants.REMOTE_ALBUM_PATH + "/";
88            this.albumInfo = new SimpleAlbumDataItem("", "", path, "", "");
89
90        }
91        let fileAsset = await item.loadFileAsset();
92        let assets = await this.getFileCopyOrMoveInfo(fileAsset, this.albumInfo);
93        if (this.menuContext.deviceId) {
94            let displayName = assets.sourceAsset.displayName;
95            let index = displayName.lastIndexOf('.');
96            let start = displayName.lastIndexOf('_');
97            displayName = `${displayName.slice(0, start)}_${new Date().getTime()}${displayName.slice(index)}`;
98            this.copy(assets.sourceAsset, null, {
99                mediaType: assets.sourceAsset.mediaType,
100                name: displayName,
101                path: this.albumInfo.relativePath
102            });
103            return;
104        }
105        if (assets.targetAsset) {
106            if (assets.targetAsset.uri == assets.sourceAsset.uri) {
107                Log.info(TAG, 'copy same fileAsset');
108                this.onOperateContinue();
109                return;
110            }
111            Log.info(TAG, 'show find same file dialog');
112            switch (this.findSameOperation) {
113                case FindSameOperation.NONE:
114                    this.menuContext.broadCast.emit(BroadcastConstants.FIND_SAME_FILE_DIALOG,
115                        [assets, this.count, () => {
116                            this.copy(assets.sourceAsset, assets.targetAsset);
117                        }, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this),
118                        this.setFindSameOperation.bind(this)]);
119                    break;
120                case FindSameOperation.REPLACE:
121                    this.copy(assets.sourceAsset, assets.targetAsset);
122                    break;
123                case FindSameOperation.SKIP:
124                    this.onOperateContinue();
125                    break;
126                default:
127                    Log.warn(TAG, `findSameOperation is error ${this.findSameOperation}`);
128                    break;
129            }
130        } else {
131            this.copy(assets.sourceAsset, null, {
132                mediaType: assets.sourceAsset.mediaType,
133                name: assets.sourceAsset.displayName,
134                path: this.albumInfo.relativePath
135            });
136        }
137    }
138
139    async copy(source, target, param?) {
140        try {
141            if (!target) {
142                startTraceWithTaskId('create', this.currentBatch);
143                target = await mediaModel.createOne(param.mediaType, param.name, param.path);
144                finishTraceWithTaskId('create', this.currentBatch);
145                if (target == null) {
146                    Log.warn(TAG, `Target file creat failed when copyFile!`);
147                    this.onError();
148                    return;
149                }
150            }
151            startTraceWithTaskId('openWriteClose', this.currentBatch);
152            await mediaModel.copyOne(source, target);
153            finishTraceWithTaskId('openWriteClose', this.currentBatch);
154            this.onCompleted();
155        } catch (error) {
156            finishTraceWithTaskId('create', this.currentBatch);
157            Log.error(TAG, `copyFile is error ${error}`);
158            this.onError();
159        }
160    }
161
162    cancelFunc(): void {
163        Log.info(TAG, `progress cancel`);
164        this.onOperatePause();
165        let cancelMessage = $r('app.string.copy_cancel_message', this.getExpectProgress().toString());
166
167        if (this.menuContext.deviceId) {
168            this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.DOWNLOAD_CANCEL_OPERATE,
169                [cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]);
170        } else {
171            this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.CANCEL_OPERATE,
172                [cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]);
173        }
174    }
175
176    // Copy cancel callback
177    onOperateContinue(): void {
178        Log.info(TAG, 'Operate Continue');
179        this.isPause = false;
180        this.cyclicOperation();
181    }
182}