1/* 2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 { Log } from '../utils/Log'; 17import { AlbumDataItem } from './AlbumDataItem'; 18import { MediaConstants } from '../constants/MediaConstants'; 19import { userFileModel } from '../base/UserFileModel'; 20import { getAlbumDisplayName } from '../base/UserFileDataHelper'; 21import photoAccessHelper from '@ohos.file.photoAccessHelper'; 22import dataSharePredicates from '@ohos.data.dataSharePredicates'; 23 24const TAG = 'AlbumDataImpl'; 25 26export class AlbumDataImpl { 27 private blackList: string[] = []; 28 private selectType: number = MediaConstants.SELECT_TYPE_ALL; 29 private deviceId: string = ''; 30 31 setBlackList(blackList: string[]): void { 32 this.blackList = blackList; 33 } 34 35 setSelectType(selectType: number): void { 36 this.selectType = selectType; 37 } 38 39 setDeviceId(deviceId: string): void { 40 this.deviceId = deviceId; 41 } 42 43 async reloadAlbumItemData(): Promise<AlbumDataItem[]> { 44 Log.info(TAG, 'reloadAlbumItemData'); 45 let albumDataItems: AlbumDataItem[] = []; 46 for (let i = 0;i < MediaConstants.ALBUM_DEFAULT_SORT_LIST.length; i++) { 47 await this.getAlbumItem(MediaConstants.ALBUM_DEFAULT_SORT_LIST[i], albumDataItems); 48 } 49 await this.getAlbumItem(MediaConstants.ALBUM_ID_USER, albumDataItems); 50 await this.getAlbumItem(MediaConstants.ALBUM_ID_RECYCLE, albumDataItems); 51 return albumDataItems; 52 } 53 54 private async getAlbumItem(id: string, albumDataItems: AlbumDataItem[]): Promise<void> { 55 Log.info(TAG, 'getAlbumItem: ' + id); 56 if (this.blackList.indexOf(id) >= 0) { 57 Log.debug(TAG, 'no need as in black list'); 58 return; 59 } 60 if (this.deviceId.length > 0 && (id !== MediaConstants.ALBUM_ID_SNAPSHOT && id !== MediaConstants.ALBUM_ID_CAMERA)) { 61 Log.info(TAG, 'no need'); 62 return; 63 } 64 let albumType = MediaConstants.ALBUM_TYPE_SYSTEM; 65 let albumSubType = MediaConstants.ALBUM_SUBTYPE_USER_GENERIC; 66 switch (id) { 67 case MediaConstants.ALBUM_ID_FAVOR: 68 albumSubType = MediaConstants.ALBUM_SUBTYPE_FAVOR; 69 break; 70 case MediaConstants.ALBUM_ID_CAMERA: 71 albumSubType = MediaConstants.ALBUM_SUBTYPE_CAMERA; 72 break; 73 case MediaConstants.ALBUM_ID_RECYCLE: 74 albumSubType = MediaConstants.ALBUM_SUBTYPE_RECYCLE; 75 break; 76 case MediaConstants.ALBUM_ID_SNAPSHOT: 77 albumSubType = MediaConstants.ALBUM_SUBTYPE_SNAPSHOT; 78 break; 79 case MediaConstants.ALBUM_ID_VIDEO: 80 albumSubType = MediaConstants.ALBUM_SUBTYPE_VIDEO; 81 break; 82 case MediaConstants.ALBUM_ID_ALL: 83 await this.getAllPhotoAlbum(albumDataItems); 84 return; 85 case MediaConstants.ALBUM_ID_USER: 86 albumType = MediaConstants.ALBUM_TYPE_USER; 87 albumSubType = MediaConstants.ALBUM_SUBTYPE_USER_GENERIC; 88 break; 89 case MediaConstants.ALBUM_ID_MOVING_PHOTO: 90 await this.getMovingPhotoAbstractAlbum(albumDataItems); 91 return; 92 default: 93 break; 94 } 95 await this.getAlbumItemByUserFileMgr(id, albumType, albumSubType, albumDataItems); 96 } 97 98 private async getAlbumItemByUserFileMgr(id: string, type: photoAccessHelper.AlbumType, subType: photoAccessHelper.AlbumSubtype, albumDataItems: AlbumDataItem[]): Promise<void> { 99 let fetchResult:photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 100 try { 101 Log.info(TAG, 'getAlbumItemByUserFileMgr'); 102 fetchResult = await userFileModel.getUserFileMgr().getAlbums(type, subType); 103 Log.info(TAG, 'type:' + type); 104 Log.info(TAG, 'subType:' + subType); 105 Log.info(TAG, 'get Album fetchResult, count: ' + fetchResult.getCount()); 106 for (let i = 0; i < fetchResult.getCount(); i++) { 107 let albumAsset:photoAccessHelper.Album = await fetchResult.getObjectByPosition(i); 108 Log.info(TAG, 'albumAsset albumType: ' + i + '---' + albumAsset.albumType); 109 Log.info(TAG, 'albumAsset albumSubType: ' + i + '---' + albumAsset.albumSubtype); 110 Log.info(TAG, 'albumAsset albumName: ' + i + '---' + albumAsset.albumName); 111 Log.info(TAG, 'albumAsset albumUri: ' + i + '---' + albumAsset.albumUri); 112 if (this.blackList.indexOf(albumAsset.albumUri) >= 0) { 113 Log.debug(TAG, 'no need as in black list:'+albumAsset.albumUri); 114 continue; 115 } 116 Log.info(TAG, 'albumAsset count: ' + i + '---' + albumAsset.count); 117 Log.info(TAG, 'albumAsset coverUri: ' + i + '---' + albumAsset.coverUri); 118 let photoFetchResult:photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null; 119 let fileAsset:photoAccessHelper.PhotoAsset = null; 120 let count = 0; 121 try { 122 let predicates = new dataSharePredicates.DataSharePredicates(); 123 let fetchOptions = { 124 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 125 predicates: predicates 126 }; 127 photoFetchResult = await albumAsset.getAssets(fetchOptions); 128 count = photoFetchResult.getCount(); 129 Log.info(TAG, 'photoFetchResult count: ' + count); 130 let displayName = 'unknown'; 131 if (id === MediaConstants.ALBUM_ID_USER) { 132 displayName = albumAsset.albumName; 133 } else { 134 displayName = await getAlbumDisplayName(id); 135 } 136 let albumType = albumAsset.albumType; 137 let albumSubType = albumAsset.albumSubtype; 138 let albumItem: AlbumDataItem = new AlbumDataItem(id, count, displayName, this.selectType, this.deviceId, albumType, albumSubType); 139 albumItem.uri = albumAsset.albumUri; 140 if (count > 0) { 141 fileAsset = await photoFetchResult.getFirstObject(); 142 Log.info(TAG, 'getFirstObject file displayName: ' + fileAsset.displayName); 143 await albumItem.update(fileAsset); 144 } 145 albumDataItems.push(albumItem); 146 } catch (err) { 147 Log.error(TAG, 'get Album getPhotoAssets failed with err: ' + err); 148 } finally { 149 if (photoFetchResult != null) { 150 photoFetchResult.close(); 151 } 152 } 153 } 154 } catch (err) { 155 Log.error(TAG, 'get Album fetchResult failed with err: ' + err); 156 } finally { 157 if (fetchResult != null) { 158 fetchResult.close(); 159 } 160 } 161 } 162 163 async getUserAlbumItemByUri(uri: string): Promise<photoAccessHelper.Album> { 164 let fetchResult:photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 165 let album: photoAccessHelper.Album = null; 166 try { 167 Log.info(TAG, 'getUserAlbumItemByUri'); 168 let predicates = new dataSharePredicates.DataSharePredicates(); 169 predicates.equalTo(photoAccessHelper.AlbumKeys.URI, uri); 170 let fetchOptions = { 171 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 172 predicates: predicates 173 }; 174 fetchResult = await userFileModel.getUserFileMgr().getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions); 175 Log.info(TAG, 'get Album fetchResult, count: ' + fetchResult.getCount()); 176 if (fetchResult.getCount() > 0) { 177 album = await fetchResult.getFirstObject(); 178 } 179 } catch (err) { 180 Log.error(TAG, 'get Album fetchResult failed with err: ' + err); 181 } finally { 182 if (fetchResult != null) { 183 fetchResult.close(); 184 } 185 } 186 return album; 187 } 188 189 async removeFileFromAlbum(albumUri: string, uri: string): Promise<boolean> { 190 let album = await this.getUserAlbumItemByUri(albumUri); 191 let fileAsset = await userFileModel.getMediaItemByUri(uri); 192 if (album != null && fileAsset != null) { 193 try { 194 await album.removeAssets([fileAsset]); 195 return true; 196 } catch (err) { 197 Log.error(TAG, 'album removePhotoAssets failed with error: ' + err); 198 } 199 } 200 return false; 201 } 202 203 async getAllPhotoAlbum(albumDataItems: AlbumDataItem[]): Promise<void> { 204 let photoFetchResult = null; 205 try { 206 let predicates = new dataSharePredicates.DataSharePredicates(); 207 let fetchOptions = { 208 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 209 predicates: predicates 210 }; 211 photoFetchResult = await userFileModel.getUserFileMgr().getAssets(fetchOptions); 212 let count = photoFetchResult.getCount(); 213 Log.info(TAG, 'getAllPhotoAlbum count: ' + count); 214 let displayName = ''; 215 let id = MediaConstants.ALBUM_ID_ALL; 216 displayName = await getAlbumDisplayName(id); 217 let albumItem: AlbumDataItem = new AlbumDataItem(id, count, displayName, this.selectType, this.deviceId, -1, -1); 218 if (count > 0) { 219 let fileAsset = await photoFetchResult.getFirstObject(); 220 await albumItem.update(fileAsset); 221 Log.info(TAG, 'getFirstObject file displayName: ' + fileAsset.displayName); 222 } 223 albumDataItems.push(albumItem); 224 } catch (err) { 225 Log.error(TAG, 'get Album getPhotoAssets failed with err: ' + err); 226 } finally { 227 if (photoFetchResult != null) { 228 photoFetchResult.close(); 229 } 230 } 231 } 232 233 async getMovingPhotoAbstractAlbum(albumDataItems: AlbumDataItem[]): Promise<void> { 234 let photoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null; 235 try { 236 let predicates = new dataSharePredicates.DataSharePredicates(); 237 predicates.equalTo(MediaConstants.PHOTO_SUBTYPE, MediaConstants.MOVING_PHOTO); 238 let fetchOptions: photoAccessHelper.FetchOptions = { 239 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 240 predicates: predicates 241 }; 242 photoFetchResult = await userFileModel.getUserFileMgr().getAssets(fetchOptions); 243 let count = photoFetchResult.getCount(); 244 Log.info(TAG, 'getMovingPhotoAbstractAlbum count: ' + count); 245 let id = MediaConstants.ALBUM_ID_MOVING_PHOTO; 246 let albumName = await getAlbumDisplayName(id); 247 let albumItem: AlbumDataItem = new AlbumDataItem(id, count, albumName, this.selectType, this.deviceId, 248 MediaConstants.ABSTRACT_ALBUM_TYPE_MOVING_PHOTO, -1); 249 if (count > 0) { 250 let fileAsset = await photoFetchResult.getFirstObject(); 251 await albumItem.update(fileAsset); 252 Log.info(TAG, 'first moving photo displayName: ' + fileAsset.displayName); 253 } 254 albumDataItems.push(albumItem); 255 } catch (err) { 256 Log.error(TAG, 'getMovingPhotoAbstractAlbum failed with err: ' + err); 257 } finally { 258 if (photoFetchResult != null) { 259 photoFetchResult.close(); 260 } 261 } 262 } 263 264 async reloadAlbumListItemData(): Promise<AlbumDataItem[]> { 265 Log.info(TAG, 'reloadAlbumListItemData start'); 266 let albumDataItems: AlbumDataItem[] = []; 267 for (let i = 0;i < MediaConstants.ALBUM_DEFAULT_SORT_LIST.length; i++) { 268 await this.getAlbumItem(MediaConstants.ALBUM_DEFAULT_SORT_LIST[i], albumDataItems); 269 } 270 await this.getCommonListAlbumItem(albumDataItems); 271 return albumDataItems; 272 } 273 274 private async getCommonListAlbumItem(albumDataItems: AlbumDataItem[]): Promise<void> { 275 let predicates = new dataSharePredicates.DataSharePredicates(); 276 let fetchOptions = { 277 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 278 predicates: predicates 279 }; 280 let albums: photoAccessHelper.Album[] = await userFileModel.getAlbums(fetchOptions); 281 await this.getAlbumDataItem(albumDataItems, albums); 282 } 283 284 private async getAlbumDataItem(albumDataItems: AlbumDataItem[], albums: photoAccessHelper.Album[]): Promise<void> { 285 for (let i = 0;i < albums.length; i++) { 286 let album: photoAccessHelper.Album = albums[i]; 287 if (this.blackList.indexOf(album.albumUri.toString()) >= 0) { 288 continue; 289 } 290 let predicates = new dataSharePredicates.DataSharePredicates(); 291 let fetchOptions = { 292 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 293 predicates: predicates 294 }; 295 let fetchFileResult = await album.getAssets(fetchOptions); 296 try { 297 let count = fetchFileResult.getCount(); 298 if (count === 0) { 299 continue; 300 } 301 let item = new AlbumDataItem(MediaConstants.ALBUM_ID_USER, count, album.albumName, this.selectType, this.deviceId, 0, 0); 302 item.uri = album.albumUri; 303 await item.update(await fetchFileResult.getFirstObject()); 304 albumDataItems.push(item); 305 } catch (err) { 306 Log.error(TAG, 'on err: ' + JSON.stringify(err)); 307 } finally { 308 fetchFileResult.close(); 309 } 310 } 311 } 312} 313