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 */
15import type { BrowserDataInterface } from '../../interface/BrowserDataInterface';
16import { AlbumDefine } from './AlbumDefine';
17import { Log } from '../../utils/Log';
18import type { FileAsset, FileAssetEx } from '../../access/UserFileManagerAccess';
19import { Album, UserFileManagerAccess } from '../../access/UserFileManagerAccess';
20import type { AsyncCallback } from '../common/AsyncCallback';
21import { Constants } from '../common/Constants';
22
23const TAG: string = 'BrowserDataImpl';
24
25export type QueryParam = {
26  albumUri: string,
27  start: number,
28  count: number,
29  filterMediaType?: string
30};
31
32export abstract class BrowserDataImpl implements BrowserDataInterface {
33  static readonly THUMBNAIL_WIDTH = 256;
34
35  abstract getData(callback: AsyncCallback<unknown> | Function, param: QueryParam): void;
36
37  abstract getDataCount(callback: AsyncCallback<unknown> | Function, param: unknown): void;
38
39  abstract getDataByUri(uri: unknown): unknown;
40
41  abstract getDataByName(name: string, albumUri: string): unknown;
42
43  abstract getDataIndexByUri(callback: AsyncCallback<unknown> | Function, param: QueryParam, uri: string): void;
44
45  abstract getMediaItemByUri(callback: AsyncCallback<unknown> | Function, uri: string): void;
46
47  async getAllObject(fetchOpt): Promise<Array<FileAsset>> {
48    Log.debug(TAG, `getAllObject ${fetchOpt}`);
49    let allObject = await UserFileManagerAccess.getInstance().getAllObject(fetchOpt);
50    return allObject;
51  }
52
53  async getCount(fetchOpt): Promise<number> {
54    let count = await UserFileManagerAccess.getInstance().getCount(fetchOpt);
55    return count;
56  }
57
58  async getFirstObject(fetchOpt): Promise<FileAssetEx> {
59    Log.debug(TAG, 'getFirstObject');
60    let firstObject: FileAssetEx = await UserFileManagerAccess.getInstance().getFirstObject(fetchOpt);
61    return firstObject;
62  }
63
64  async getObject(fetchOpt): Promise<FileAsset> {
65    Log.debug(TAG, 'getFirstObject');
66    let object: FileAsset = await UserFileManagerAccess.getInstance().getObject(fetchOpt);
67    return object;
68  }
69
70  async getItems(albumUri?: string, startIndex?: number, count?: number, filterMediaType?: string): Promise<Array<FileAsset>> {
71    let result: Array<FileAsset> = null;
72
73    // albumUri不为空,则从目标相册中获取;否则默认从所有媒体资源中获取
74    if (albumUri) {
75      let album: Album = await UserFileManagerAccess.getInstance().getAlbumByUri(albumUri);
76      let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType);
77      if (album) {
78        let fetchResult = await album.getPhotoAssets(fetchOpt);
79        result = await fetchResult.getAllObject();
80        fetchResult.close();
81      }
82    } else {
83      let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType);
84      Log.debug(TAG, `getMediaItem start ${JSON.stringify(fetchOpt)}`);
85      result = await UserFileManagerAccess.getInstance().getAllObject(fetchOpt);
86    }
87    return result;
88  }
89
90  async getItemsCountOfAlbum(album: Album, filterMediaType?: string): Promise<number> {
91    let count = 0;
92    // 当前相册count始终为0,先通过查全部图片获取count
93    let fetchOpt = AlbumDefine.getFileFetchOptWithEmptyColumn(Constants.INVALID, Constants.INVALID, filterMediaType);
94    let fetchResult = await album.getPhotoAssets(fetchOpt);
95    count = fetchResult.getCount();
96    fetchResult.close();
97    return count;
98  }
99
100  async getItemsCount(albumUri?: string, filterMediaType?: string): Promise<number> {
101    let count = 0;
102    if (albumUri) {
103      let album: Album = await UserFileManagerAccess.getInstance().getAlbumByUri(albumUri);
104      // 当前相册count始终为0,先通过查全部图片获取count
105      let fetchOpt = AlbumDefine.getFileFetchOpt(Constants.INVALID, Constants.INVALID, filterMediaType);
106      let fetchResult = await album.getPhotoAssets(fetchOpt);
107      count = fetchResult.getCount();
108      fetchResult.close();
109    } else {
110      let fetchOpt = AlbumDefine.getFileFetchOpt(undefined, undefined, filterMediaType);
111      count = await this.getCount(fetchOpt);
112    }
113    return count;
114  }
115
116  async getItemIndexByUri(uri: string, albumUri?: string): Promise<number> {
117    let index: number = Constants.INVALID;
118    let realUri: string = uri;
119    let realAlbumUri: string = albumUri;
120    let allObject: Array<FileAsset> = null;
121    Log.debug(TAG, `getItemIndexByUri uri: ${uri}, albumUri: ${albumUri}`);
122    if (!uri.startsWith(UserFileManagerAccess.REGISTER_TYPE_ALL_PHOTOS)) {
123      let targetObject: FileAsset = await this.getItemByUri(uri);
124      if (targetObject) {
125        Log.debug(TAG, `find photo for uri: ${realUri}=>${targetObject.uri}`);
126        realUri = targetObject.uri;
127      }
128    }
129    Log.debug(TAG, `getItemIndexByUri real uri: ${realUri}`);
130    if (albumUri && albumUri.length > 0) {
131      if (!albumUri.startsWith(UserFileManagerAccess.REGISTER_TYPE_ALL_ALBUMS)) {
132        let targetAlbum: Album = await UserFileManagerAccess.getInstance().getAlbumByUri(albumUri);
133        if (targetAlbum) {
134          Log.debug(TAG, `find album for uri: ${realAlbumUri}=>${targetAlbum.albumUri}`);
135          realAlbumUri = targetAlbum.albumUri;
136        }
137      }
138    } else {
139      realAlbumUri = "";
140    }
141    Log.debug(TAG, `getItemIndexByUri real album uri: ${realAlbumUri}`);
142    allObject = await this.getItems(realAlbumUri);
143    if (allObject) {
144      Log.debug(TAG, `getItemIndexByUri count: ${allObject.length}`);
145      index = allObject.findIndex((item: FileAsset) => item.uri == realUri);
146    }
147    return index;
148  }
149
150  async getItemByUri(uri: string): Promise<FileAsset> {
151    let object: FileAsset = null;
152    let fetchOpt = AlbumDefine.getFileFetchOptByUri(uri);
153    object = await this.getObject(fetchOpt);
154    return object;
155  }
156
157  getThumbnailSafe(sourceUri: string, path: string, size?): string {
158    try {
159      if (size) {
160        if (size.width != 0 && size.height != 0) {
161          return `${sourceUri}?oper=thumbnail&width=${size.width}&height=${size.height}&path=${path}`;
162        } else {
163          Log.warn(TAG, 'getThumbnailSafe with width==0 and height==0, so do not use thumbnail' + JSON.stringify(size));
164          return `${sourceUri}`;
165        }
166      } else {
167        return `${sourceUri}?oper=thumbnail&width=${BrowserDataImpl.THUMBNAIL_WIDTH}&height=${BrowserDataImpl.THUMBNAIL_WIDTH}&path=${path}`;
168      }
169    } catch (err) {
170      Log.warn(TAG, `get Thumbnail Failed! msg:${err}`);
171      return null;
172    }
173  }
174}