1// @ts-nocheck 2/* 3 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import fileIO from '@ohos.fileio'; 18import { stashOrGetObject } from '../utils/SingleInstanceUtils'; 19import { Log } from '../utils/Log'; 20import { hiSysEventDataQueryTimedOut } from '../utils/hisysEventUtil'; 21import photoAccessHelper from '@ohos.file.photoAccessHelper'; 22import dataSharePredicates from '@ohos.data.dataSharePredicates'; 23import { MediaConstants } from '../constants/MediaConstants' 24import { getSystemAlbumDisplayName } from './UserFileDataHelper'; 25import { SimpleAlbumDataItem } from '../common/SimpleAlbumDataItem'; 26 27const TAG = 'UserFileModel'; 28 29export class UserFileModelItem { 30 fileAsset: photoAccessHelper.PhotoAsset; 31 counts: number; 32} 33 34class UserFileModel { 35 private userFileMgr: photoAccessHelper.PhotoAccessHelper = undefined; 36 37 constructor() { 38 } 39 40 onCreate(context): void { 41 if (this.userFileMgr == undefined) { 42 this.userFileMgr = photoAccessHelper.getPhotoAccessHelper(context); 43 } 44 } 45 46 getUserFileMgr(): photoAccessHelper.PhotoAccessHelper { 47 return this.userFileMgr; 48 } 49 50 async createOne(displayName: string, albumUri: string): Promise<photoAccessHelper.PhotoAsset> { 51 Log.info(TAG, 'createOne displayName:' + displayName + ' albumUri: ' + albumUri); 52 let fileAsset = await this.userFileMgr.createAsset(displayName, albumUri); 53 let album = await this.getUserAlbumItemByUri(albumUri); 54 await album.addAssets([fileAsset]); 55 return fileAsset; 56 } 57 58 async getUserAlbumItemByUri(uri: string): Promise<photoAccessHelper.Album> { 59 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 60 let album: photoAccessHelper.Album = null; 61 try { 62 Log.info(TAG, 'getUserAlbumItemByUri'); 63 let predicates = new dataSharePredicates.DataSharePredicates(); 64 predicates.equalTo(photoAccessHelper.AlbumKeys.URI, uri); 65 let fetchOptions = { 66 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 67 predicates: predicates 68 }; 69 fetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions); 70 Log.info(TAG, 'get Album fetchResult, count: ' + fetchResult.getCount()); 71 if (fetchResult.getCount() > 0) { 72 album = fetchResult.getFirstObject(); 73 } 74 } catch (err) { 75 Log.error(TAG, 'get Album fetchResult failed with err: ' + err); 76 } finally { 77 if (fetchResult != null) { 78 fetchResult.close(); 79 } 80 } 81 return album; 82 } 83 84 async copyOne(source: photoAccessHelper.PhotoAsset, target: photoAccessHelper.PhotoAsset): Promise<void> { 85 Log.info(TAG, 'copy start: src:' + source.uri + ' target: ' + target.uri); 86 let fd: Number = await this.openAsset('R', source); 87 if (fd <= 0) { 88 throw new Error('fd is invalid'); 89 } 90 91 let targetFd: Number = await this.openAsset('RW', target); 92 if (targetFd <= 0) { 93 throw new Error('targetFd is invalid'); 94 } 95 96 await fileIO.copyFile(fd, targetFd); 97 98 await this.closeAsset(fd, source); 99 await this.closeAsset(targetFd, target); 100 101 Log.debug(TAG, 'copy end'); 102 } 103 104 async deleteOne(uri: string): Promise<void> { 105 Log.debug(TAG, 'deleteAsset uri: ' + uri); 106 try { 107 await this.userFileMgr.deleteAssets([uri]); 108 } catch (err) { 109 Log.error(TAG, 'deleteOne with error: ' + err); 110 } 111 } 112 113 async recover(fileAsset: photoAccessHelper.PhotoAsset): Promise<void> { 114 let albumFetchResult = null; 115 try { 116 Log.debug(TAG, 'recoverPhotoAssetsDemoPromise:' + fileAsset.displayName); 117 albumFetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.SYSTEM, photoAccessHelper.AlbumSubtype.TRASH); 118 let album = await albumFetchResult.getFirstObject(); 119 Log.debug(TAG, 'album get'); 120 album.recoverAssets([fileAsset]).then(() => { 121 Log.debug(TAG, 'album recoverPhotoAssets successfully'); 122 }).catch((err) => { 123 Log.info(TAG, 'album recoverPhotoAssets failed with error: ' + err); 124 }); 125 } catch (err) { 126 Log.error(TAG, 'recoverPhotoAssetsDemoPromise failed with error: ' + err); 127 } finally { 128 if (albumFetchResult != null) { 129 albumFetchResult.close(); 130 } 131 } 132 } 133 134 async permanentDelete(fileAsset: photoAccessHelper.PhotoAsset): Promise<void> { 135 let albumFetchResult = null; 136 try { 137 Log.debug(TAG, 'permanentDelete'); 138 albumFetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.SYSTEM, photoAccessHelper.AlbumSubtype.TRASH); 139 let album = await albumFetchResult.getFirstObject(); 140 album.deleteAssets([fileAsset]).then(() => { 141 Log.debug('album deletePhotoAssets successfully'); 142 }).catch((err) => { 143 Log.error(TAG, 'album deletePhotoAssets failed with error: ' + err); 144 }); 145 } catch (err) { 146 Log.error(TAG, 'permanentDelete failed with error: ' + err); 147 } finally { 148 if (albumFetchResult != null) { 149 albumFetchResult.close(); 150 } 151 } 152 } 153 154 async createAlbum(albumName: string): Promise<SimpleAlbumDataItem> { 155 let newAlbum: SimpleAlbumDataItem = undefined; 156 try { 157 let album = await this.userFileMgr.createAlbum(albumName); 158 newAlbum = new SimpleAlbumDataItem(MediaConstants.ALBUM_ID_USER, albumName, album.albumUri, 159 '', '', MediaConstants.ALBUM_TYPE_USER, MediaConstants.ALBUM_SUBTYPE_USER_GENERIC); 160 } catch (err) { 161 Log.error(TAG, 'createAlbum failed with error: ' + err); 162 } 163 return newAlbum; 164 } 165 166 async deleteAlbum(albumName: string): Promise<void> { 167 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 168 try { 169 let predicates = new dataSharePredicates.DataSharePredicates(); 170 predicates.equalTo(photoAccessHelper.AlbumKeys.ALBUM_NAME, albumName); 171 let fetchOptions = { 172 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 173 predicates: predicates 174 }; 175 fetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions); 176 for (let i = 0; i < fetchResult.getCount(); i++) { 177 let albumAsset = await fetchResult.getObjectByPosition(i); 178 Log.info(TAG, 'deleteAlbum albumUri' + albumAsset.albumUri); 179 Log.info(TAG, 'deleteAlbum albumName' + albumAsset.albumName); 180 this.userFileMgr.deleteAlbums([albumAsset]).then(() => { 181 Log.info(TAG, 'deletePhotoAlbumsPromise successfully'); 182 }).catch((err) => { 183 Log.error(TAG, 'deletePhotoAlbumsPromise failed with err: ' + err); 184 }); 185 } 186 } catch (err) { 187 Log.error(TAG, 'deletePhotoAlbumsPromise failed with error: ' + err); 188 } finally { 189 if (fetchResult != null) { 190 fetchResult.close(); 191 } 192 } 193 } 194 195 async deleteAll(fetchOption: photoAccessHelper.FetchOptions): Promise<void> { 196 Log.info(TAG, 'deleteAll'); 197 let fetchFileResult: photoAccessHelper.FetchResult = null; 198 try { 199 fetchFileResult = await this.userFileMgr.getAssets(fetchOption); 200 Log.debug(TAG, 'deleteAll getPhotoAssets'); 201 let deleteAllGetAllObject = hiSysEventDataQueryTimedOut('deleteAllGetAllObject'); 202 let fileAssets: photoAccessHelper.PhotoAsset[] = await fetchFileResult.getAllObject(); 203 clearTimeout(deleteAllGetAllObject); 204 for (let i = 0;i < fileAssets.length; i++) { 205 await this.deleteOne(fileAssets[i].uri); 206 } 207 Log.debug(TAG, 'deleteAll getFirstObject'); 208 } catch (err) { 209 Log.error(TAG, 'deleteAll error:' + JSON.stringify(err)); 210 } finally { 211 if (fetchFileResult != null) { 212 fetchFileResult.close(); 213 } 214 } 215 Log.debug(TAG, 'deleteAll finish'); 216 } 217 218 async getAllMediaItems(): Promise<photoAccessHelper.PhotoAsset[]> { 219 let fileAssets: photoAccessHelper.PhotoAsset[] = []; 220 let photoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null; 221 try { 222 let predicates = new dataSharePredicates.DataSharePredicates(); 223 let emptyFetchOption = { 224 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 225 predicates: predicates 226 }; 227 photoFetchResult = await this.userFileMgr.getAssets(emptyFetchOption); 228 Log.info(TAG, 'getAllMediaItems count: ' + photoFetchResult.getCount()); 229 for (let i = 0;i < photoFetchResult.getCount(); i++) { 230 fileAssets.push(await photoFetchResult.getObjectByPosition(i)); 231 } 232 } catch (err) { 233 Log.error(TAG, 'getAllMediaItems failed with err: ' + err); 234 } finally { 235 if (photoFetchResult != null) { 236 photoFetchResult.close(); 237 } 238 } 239 return fileAssets; 240 } 241 242 async getAllMediaItemsByType(type: number, subType: number, albumFetchOption, fileFetchOption): Promise<photoAccessHelper.PhotoAsset[]> { 243 let fileAssets: photoAccessHelper.PhotoAsset[] = []; 244 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 245 try { 246 Log.info(TAG, 'getAllMediaItemsByUserFile'); 247 Log.info(TAG, 'type:' + type); 248 Log.info(TAG, 'subType:' + subType); 249 if (type === photoAccessHelper.AlbumType.USER && albumFetchOption != null) { 250 Log.info(TAG, 'albumFetchOption != null'); 251 fetchResult = await this.userFileMgr.getAlbums(type, subType, albumFetchOption); 252 } else { 253 fetchResult = await this.userFileMgr.getAlbums(type, subType); 254 } 255 Log.info(TAG, 'get Album fetchResult, count: ' + fetchResult.getCount()); 256 for (let i = 0; i < fetchResult.getCount(); i++) { 257 let albumAsset: photoAccessHelper.Album = await fetchResult.getObjectByPosition(i); 258 let photoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null; 259 try { 260 photoFetchResult = await albumAsset.getAssets(fileFetchOption); 261 for (let i = 0; i < photoFetchResult.getCount(); i++) { 262 let photoAsset = await photoFetchResult.getObjectByPosition(i); 263 fileAssets.push(photoAsset); 264 Log.info(TAG, 'getPhotoAssets successfully, file displayName: ' + photoAsset.displayName); 265 } 266 } catch (err) { 267 Log.info(TAG, 'get Album getPhotoAssets failed with err: ' + err); 268 } finally { 269 if (photoFetchResult != null) { 270 photoFetchResult.close(); 271 } 272 } 273 } 274 } catch (err) { 275 Log.error(TAG, 'get Album fetchResult failed with err: ' + err); 276 } finally { 277 if (fetchResult != null) { 278 fetchResult.close(); 279 } 280 } 281 Log.info(TAG, 'fileAssets: ' + fileAssets.length); 282 return fileAssets; 283 } 284 285 async getMediaItemByUriFromTrash(uri: string): Promise<photoAccessHelper.PhotoAsset> { 286 Log.info(TAG, 'getMediaItemByUriFromTrash'); 287 Log.info(TAG, 'uri:' + uri); 288 let albumFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> = null; 289 let fileAsset: photoAccessHelper.PhotoAsset = null; 290 try { 291 albumFetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.SYSTEM, photoAccessHelper.AlbumSubtype.TRASH); 292 let albumAsset = await albumFetchResult.getFirstObject(); 293 let photoFetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null; 294 try { 295 let predicates = new dataSharePredicates.DataSharePredicates(); 296 let emptyFetchOption = { 297 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 298 predicates: predicates 299 }; 300 photoFetchResult = await albumAsset.getAssets(emptyFetchOption); 301 for (let i = 0; i < photoFetchResult.getCount(); i++) { 302 let photoAsset = await photoFetchResult.getObjectByPosition(i); 303 if (photoAsset.uri === uri) { 304 fileAsset = photoAsset; 305 Log.info(TAG, 'getMediaItemByUriFromTrash success: ' + photoAsset.displayName); 306 break; 307 } 308 } 309 } catch (err) { 310 Log.info(TAG, 'getMediaItemByUriFromTrash getPhotoAssets failed with err: ' + err); 311 } finally { 312 if (photoFetchResult != null) { 313 photoFetchResult.close(); 314 } 315 } 316 } catch (err) { 317 Log.error(TAG, 'getMediaItemByUriFromTrash failed with error: ' + err); 318 } finally { 319 if (albumFetchResult != null) { 320 albumFetchResult.close(); 321 } 322 } 323 return fileAsset; 324 } 325 326 async getMediaItemByUri(uri: string): Promise<photoAccessHelper.PhotoAsset> { 327 Log.info(TAG, 'getMediaItemByUri'); 328 Log.info(TAG, 'uri:' + uri); 329 let predicates = new dataSharePredicates.DataSharePredicates(); 330 predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uri); 331 let fetchOptions = { 332 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 333 predicates: predicates 334 }; 335 let fileAsset: photoAccessHelper.PhotoAsset = null; 336 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = null 337 try { 338 Log.info(TAG, 'fetchResult start'); 339 fetchResult = await this.userFileMgr.getAssets(fetchOptions); 340 Log.info(TAG, 'fetchResult count ' + fetchResult.getCount()); 341 fileAsset = await fetchResult.getFirstObject(); 342 Log.info(TAG, 'fileAsset ' + fileAsset.displayName); 343 } catch (err) { 344 Log.error(TAG, 'getMediaItemByUri failed, message = ' + err); 345 } finally { 346 if (fetchResult != null) { 347 fetchResult.close(); 348 } 349 } 350 return fileAsset; 351 } 352 353 async getMediaItemCountsByDisplayName(displayName: string): Promise<number> { 354 Log.info(TAG, 'getMediaItemCountsByDisplayName'); 355 let count = 0; 356 let fetchFileResult: photoAccessHelper.FetchResult = null; 357 let predicates = new dataSharePredicates.DataSharePredicates(); 358 predicates.equalTo(photoAccessHelper.PhotoKeys.DISPLAY_NAME, displayName); 359 let fetchOptions = { 360 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 361 predicates: predicates 362 }; 363 try { 364 fetchFileResult = await this.userFileMgr.getAssets(fetchOptions); 365 Log.debug(TAG, 'getMediaItemCountsByDisplayName getPhotoAssets'); 366 count = await fetchFileResult.getCount(); 367 } catch (err) { 368 Log.error(TAG, 'getMediaItemCountsByDisplayName error:' + JSON.stringify(err)); 369 } finally { 370 if (fetchFileResult != null) { 371 fetchFileResult.close(); 372 } 373 } 374 Log.debug(TAG, 'getMediaItemCountsByDisplayName finish'); 375 return count; 376 } 377 378 async getUserAlbumCountByName(albumName: string): Promise<number> { 379 Log.info(TAG, 'getUserAlbumCountByName'); 380 Log.info(TAG, 'album_name:' + albumName); 381 let count = 0; 382 let systemAlbums = await getSystemAlbumDisplayName(); 383 if (systemAlbums.indexOf(albumName) >= 0) { 384 return 1; 385 } 386 let fetchResult: photoAccessHelper.FetchResult = null; 387 try { 388 let predicates = new dataSharePredicates.DataSharePredicates(); 389 predicates.equalTo(photoAccessHelper.AlbumKeys.ALBUM_NAME, albumName); 390 let fetchOptions = { 391 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 392 predicates: predicates 393 }; 394 fetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions); 395 Log.info(TAG, 'fetchResult' + fetchResult.getCount()); 396 count = fetchResult.getCount(); 397 } catch (err) { 398 Log.error(TAG, 'getUserAlbumCountByName error:' + JSON.stringify(err)); 399 } finally { 400 if (fetchResult != null) { 401 fetchResult.close(); 402 } 403 } 404 Log.debug(TAG, 'getUserAlbumCountByName finish'); 405 return count; 406 } 407 408 async getActivePeers(): Promise<photoAccessHelper.PeerInfo[]> { 409 Log.info(TAG, 'getActivePeers'); 410 let peers: photoAccessHelper.PeerInfo[] = []; 411 try { 412 let getActivePeers = hiSysEventDataQueryTimedOut('getActivePeers') 413 peers = await this.userFileMgr.getActivePeers(); 414 clearTimeout(getActivePeers); 415 } catch (err) { 416 Log.error(TAG, 'getActivePeers error:' + JSON.stringify(err)); 417 } 418 Log.debug(TAG, 'getActivePeers finish'); 419 return peers; 420 } 421 422 async getUserAlbumByName(albumName: string): Promise<photoAccessHelper.Album> { 423 Log.info(TAG, 'getUserAlbumByName'); 424 Log.info(TAG, 'album_name' + albumName); 425 let fetchResult: photoAccessHelper.FetchResult = null; 426 let album = null; 427 try { 428 let predicates = new dataSharePredicates.DataSharePredicates(); 429 predicates.equalTo(photoAccessHelper.AlbumKeys.ALBUM_NAME, albumName); 430 let fetchOptions = { 431 fetchColumns: MediaConstants.EMPTY_FETCH_COLUMNS, 432 predicates: predicates 433 }; 434 fetchResult = await this.userFileMgr.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, fetchOptions); 435 Log.info(TAG, 'fetchResult' + fetchResult.getCount()); 436 if (fetchResult.getCount() > 0) { 437 album = fetchResult.getFirstObject(); 438 } 439 } catch (err) { 440 Log.error(TAG, 'getUserAlbumByName error:' + JSON.stringify(err)); 441 } finally { 442 if (fetchResult != null) { 443 fetchResult.close(); 444 } 445 } 446 Log.debug(TAG, 'getUserAlbumByName finish'); 447 return album; 448 } 449 450 async getAlbums(fetchOption: photoAccessHelper.FetchOptions): Promise<photoAccessHelper.Album[]> { 451 Log.info(TAG, 'getAlbums'); 452 let albums: photoAccessHelper.Album[] = []; 453 try { 454 albums = await this.userFileMgr.getAlbums(fetchOption); 455 Log.info(TAG, 'getAlbums albums ' + albums.getCounts()); 456 } catch (err) { 457 Log.error(TAG, 'getAlbums error:' + JSON.stringify(err)); 458 } 459 Log.debug(TAG, 'getAlbums finish'); 460 return albums; 461 } 462 463 async openAsset(mode: string, fileAsset: photoAccessHelper.PhotoAsset): Promise<number> { 464 Log.debug(TAG, 'openAsset start'); 465 let fd: number = await fileAsset.open(mode); 466 Log.info(TAG, 'openAsset end. fd: ' + fd); 467 if (fd <= 0) { 468 Log.info(TAG, 'openAsset Fail'); 469 } 470 return fd; 471 } 472 473 async closeAsset(fd: number, fileAsset: photoAccessHelper.PhotoAsset): Promise<void> { 474 Log.debug(TAG, 'closeAsset start'); 475 await fileAsset.close(fd); 476 } 477 478 async addPhotoToAlbumByUserFileMgr(albumUri: string, uri: string): Promise<void> { 479 Log.info(TAG, 'addPhotoAssetsDemoPromise'); 480 Log.info(TAG, 'albumUri' + albumUri); 481 Log.info(TAG, 'mediaItem.uri' + uri); 482 try { 483 let album = await this.getUserAlbumItemByUri(albumUri); 484 let predicates = new dataSharePredicates.DataSharePredicates(); 485 predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uri); 486 let fetchOptions = { 487 fetchColumns: MediaConstants.FILE_ASSET_FETCH_COLUMNS, 488 predicates: predicates 489 }; 490 this.userFileMgr.getAssets(fetchOptions, async (err, fetchResult) => { 491 if (fetchResult != undefined) { 492 Log.info(TAG, 'fetchResult success'); 493 let fileAsset = await fetchResult.getFirstObject(); 494 if (fileAsset != undefined) { 495 Log.info(TAG, 'addPhotoToAlbumByUserFileMgr photo displayName : ' + fileAsset.displayName); 496 album.addAssets([fileAsset]).then(() => { 497 Log.info(TAG, 'album addPhotoAssets successfully'); 498 }).catch((err) => { 499 Log.info(TAG, 'album addPhotoAssets failed with error: ' + err); 500 }); 501 } 502 fetchResult.close(); 503 } else { 504 Log.info(TAG, 'fetchResult fail' + err); 505 } 506 }); 507 } catch (err) { 508 Log.error(TAG, 'addPhotoAssetsDemoPromise failed with error: ' + err); 509 } 510 } 511} 512 513export let userFileModel: UserFileModel = stashOrGetObject<UserFileModel>(new UserFileModel(), TAG); 514