1/* 2 * Copyright (c) 2021-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 { MediaData } from './MediaData'; 17import { Constants } from '../common/Constants'; 18import { AlbumDefine, DataStoreUtil, Log, MediaConstants, UserFileManagerAccess, } from '@ohos/common'; 19import resourceManager from '@ohos.resourceManager'; 20import type { FormListener } from '../controller/FormController'; 21import userFileManager from '@ohos.filemanagement.userFileManager'; 22 23const TAG: string = 'formA_MediaDataManager'; 24 25let dataStore = DataStoreUtil.getInstance(); 26 27export class MediaDataManager { 28 private mediaData: MediaData = null; 29 private formController: FormListener = null; 30 private items: userFileManager.FileAsset[]; 31 private fd: number = -1; 32 private operationMode: number = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 33 private isNextFag: boolean = true; 34 private isUpdate: boolean = false; 35 private mediaModel = UserFileManagerAccess.getInstance(); 36 37 constructor(operationMode: number, formController: FormListener) { 38 this.formController = formController; 39 this.operationMode = operationMode; 40 } 41 42 async initData(formId: string): Promise<void> { 43 Log.info('getAllObject getFileAssets', `initData formId ${formId}`); 44 await this.storageRead(formId); 45 await this.initShowName(); 46 if (this.mediaData == null || this.mediaData == undefined) { 47 Log.info(TAG, `initData new MediaData! form ${formId}`); 48 let mgr: resourceManager.ResourceManager = globalThis.formContext.resourceManager; 49 let displayName = await mgr.getStringValue($r('app.string.album_photos').id); 50 let albumUri = this.mediaModel.getSystemAlbumUri(UserFileManagerAccess.IMAGE_ALBUM_SUB_TYPE); 51 this.mediaData = new MediaData(formId, displayName, displayName, albumUri, '', 0, 52 Constants.PHOTOS_FORM_DEFAULT_PERIOD, 1, 0); 53 Log.info(TAG, `initData new MediaData! end ${formId}`); 54 } 55 await this.loadData(); 56 } 57 58 async initShowName(): Promise<number> { 59 let isShowKey = Constants.FROM_PLAYBACK_ISSHOWNAME; 60 let isShow = await dataStore.getData(isShowKey, 1) as number; 61 AppStorage.SetOrCreate(Constants.FROM_PLAYBACK_ISSHOWNAME, isShow); 62 Log.debug(TAG, `initShowName dataStoreData:${isShow}` + 63 `storageData:${AppStorage.Get(Constants.FROM_PLAYBACK_ISSHOWNAME)}`); 64 return isShow; 65 } 66 67 async saveData(): Promise<void> { 68 Log.debug(TAG, 'saveData'); 69 this.updateMediaData(); 70 if (((this.operationMode != Constants.PHOTOS_FORM_OPERATION_MODE_EVENT) 71 && (this.operationMode != Constants.PHOTOS_FORM_OPERATION_MODE_DESTROY) 72 && (this.operationMode != Constants.PHOTOS_FORM_OPERATION_MODE_UPDATE)) || this.isUpdate) { 73 try { 74 this.fd = await this.openCurrentFd(); 75 } catch (error) { 76 Log.error(TAG, `open Fd failed: ${error}`); 77 } 78 } 79 Log.debug(TAG, `saveData fd: ${this.fd}`); 80 await this.storageSet(); 81 this.operationFormController(); 82 } 83 84 operationFormController(): void { 85 Log.debug(TAG, `operFormControllerOper operationMode ${this.operationMode}`); 86 let formId: string = this.mediaData.formId; 87 switch (this.operationMode) { 88 case Constants.PHOTOS_FORM_OPERATION_MODE_DESTROY: 89 this.operationMode = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 90 this.formController.onDeleteForm(formId); 91 break; 92 case Constants.PHOTOS_FORM_OPERATION_MODE_UPDATE: 93 this.operationMode = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 94 this.formController.onUpdateFormData(formId); 95 break; 96 case Constants.PHOTOS_FORM_OPERATION_MODE_EVENT: 97 this.operationMode = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 98 this.formController.onEvent(formId); 99 break; 100 case Constants.PHOTOS_FORM_OPERATION_MODE_CALLBACK: 101 this.operationMode = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 102 this.formController.onCallback(formId); 103 break; 104 case Constants.PHOTOS_FORM_OPERATION_IS_SHOW_AlbumName: 105 this.operationMode = Constants.PHOTOS_FORM_OPERATION_MODE_NONE; 106 this.formController.onShowForm(formId); 107 break; 108 default: 109 this.formController.updateFormData(formId); 110 break; 111 } 112 Log.debug(TAG, 'operationFormController end!'); 113 } 114 115 async storageRead(formId: string): Promise<void> { 116 Log.debug(TAG, 'storageRead start!'); 117 let formIdKey: string = 'formId_' + formId; 118 let hasFormId = await dataStore.hasData(formIdKey); 119 Log.debug(TAG, `The value of hasFormId is ${hasFormId}`); 120 if (hasFormId) { 121 let displayNameKey = 'displayName_' + formId; 122 let displayName = await dataStore.getData(displayNameKey, '') as string; 123 Log.debug(TAG, `The value of albumName is ${displayName}`); 124 let albumNameKey = 'albumName_' + formId; 125 let albumName = await dataStore.getData(albumNameKey, '') as string; 126 Log.debug(TAG, `The value of albumName is ${albumName}`); 127 let albumUriKey = 'albumUri_' + formId; 128 let albumUri = await dataStore.getData(albumUriKey, '') as string; 129 Log.debug(TAG, `The value of albumUri is ${albumUri}`); 130 let currentUriKey = 'currentUri_' + formId; 131 let currentUri = await dataStore.getData(currentUriKey, '') as string; 132 Log.debug(TAG, `The value of currentUri is ${currentUri}`); 133 let currentIndexKey = 'currentIndex_' + formId; 134 let currentIndex = await dataStore.getData(currentIndexKey, 0) as number; 135 Log.debug(TAG, `The value of currentIndex is ${currentIndex}`); 136 let intervalTimeKey = 'intervalTime_' + formId; 137 let intervalTime = await dataStore.getData(intervalTimeKey, 0) as number; 138 Log.debug(TAG, `The value of intervalTime is ${intervalTime}`); 139 let isShowKey = 'isShowAlbums_' + formId; 140 let isShow = await dataStore.getData(isShowKey, 0) as number; 141 Log.debug(TAG, `The value of isShow is ${isShow}`); 142 let arkUriKey = 'arkUri_' + formId; 143 let arkUri = await dataStore.getData(arkUriKey, 0) as number; 144 Log.debug(TAG, `The value of arkUri is ${arkUri}`); 145 if (arkUri == 0) { 146 arkUri = 1; 147 } else { 148 arkUri = 0; 149 } 150 this.mediaData = new MediaData(formId, displayName, albumName, albumUri, 151 currentUri, currentIndex, intervalTime, isShow, arkUri); 152 } 153 Log.debug(TAG, 'storageRead end!'); 154 } 155 156 async storageSet(): Promise<void> { 157 Log.debug(TAG, 'storageSet start!'); 158 let formIdKey = 'formId_' + this.mediaData.formId; 159 await dataStore.putData(formIdKey, this.mediaData.formId); 160 let displayNameKey = 'displayName_' + this.mediaData.formId; 161 await dataStore.putData(displayNameKey, this.mediaData.displayName); 162 let albumNameKey = 'albumName_' + this.mediaData.formId; 163 await dataStore.putData(albumNameKey, this.mediaData.albumName); 164 let albumUriKey = 'albumUri_' + this.mediaData.formId; 165 await dataStore.putData(albumUriKey, this.mediaData.albumUri); 166 let currentUriKey = 'currentUri_' + this.mediaData.formId; 167 await dataStore.putData(currentUriKey, this.mediaData.currentUri); 168 let currentIndexKey = 'currentIndex_' + this.mediaData.formId; 169 await dataStore.putData(currentIndexKey, this.mediaData.currentIndex); 170 let intervalTimeKey = 'intervalTime_' + this.mediaData.formId; 171 await dataStore.putData(intervalTimeKey, this.mediaData.intervalTime); 172 let isShowKey = 'isShowAlbums_' + this.mediaData.formId; 173 await dataStore.putData(isShowKey, this.mediaData.isShowAlbum); 174 let arkUriKey = 'arkUri_' + this.mediaData.formId; 175 await dataStore.putData(arkUriKey, this.mediaData.arkUri); 176 await dataStore.flush(); 177 Log.debug(TAG, 'storageSet end!'); 178 } 179 180 async storageDelete(): Promise<void> { 181 Log.debug(TAG, 'storageDelete start!'); 182 let formIdKey = 'formId_' + this.mediaData.formId; 183 if (await dataStore.hasData(formIdKey)) { 184 Log.debug(TAG, 'storageDelete formId'); 185 await dataStore.delData(formIdKey); 186 } 187 let displayNameKey = 'displayName_' + this.mediaData.formId; 188 if (await dataStore.hasData(displayNameKey)) { 189 Log.debug(TAG, 'storageDelete displayName'); 190 await dataStore.delData(displayNameKey); 191 } 192 let albumNameKey = 'albumName_' + this.mediaData.formId; 193 if (await dataStore.hasData(albumNameKey)) { 194 Log.debug(TAG, 'storageDelete albumName'); 195 await dataStore.delData(albumNameKey); 196 } 197 let albumUriKey = 'albumUri_' + this.mediaData.formId; 198 if (await dataStore.hasData(albumUriKey)) { 199 Log.debug(TAG, 'storageDelete albumUri'); 200 await dataStore.delData(albumUriKey); 201 } 202 let currentUriKey = 'currentUri_' + this.mediaData.formId; 203 if (await dataStore.hasData(currentUriKey)) { 204 Log.debug(TAG, 'storageDelete currentUri'); 205 await dataStore.delData(currentUriKey); 206 } 207 let currentIndexKey = 'currentIndex_' + this.mediaData.formId; 208 if (await dataStore.hasData(currentIndexKey)) { 209 Log.debug(TAG, 'storageDelete currentIndex'); 210 await dataStore.delData(currentIndexKey); 211 } 212 let intervalTimeKey = 'intervalTime_' + this.mediaData.formId; 213 if (await dataStore.hasData(intervalTimeKey)) { 214 Log.debug(TAG, 'storageDelete intervalTime'); 215 await dataStore.delData(intervalTimeKey); 216 } 217 let isShowKey = 'isShowAlbums_' + this.mediaData.formId; 218 if (await dataStore.hasData(isShowKey)) { 219 Log.debug(TAG, 'storageDelete isShowAlbumName'); 220 await dataStore.delData(isShowKey); 221 } 222 let arkUriKey = 'arkUri_' + this.mediaData.formId; 223 if (await dataStore.hasData(arkUriKey)) { 224 Log.debug(TAG, 'storageDelete arkUri'); 225 await dataStore.delData(arkUriKey); 226 } 227 await dataStore.flush(); 228 Log.debug(TAG, 'storageDelete end!'); 229 } 230 231 updateMediaData(): void { 232 Log.debug(TAG, `updateMediaData start! index ${this.mediaData.currentIndex}`); 233 if (this.mediaData.currentIndex == -1) { 234 this.mediaData.currentIndex = 0; 235 this.isNextFag = false; 236 } else if (this.mediaData.currentIndex >= this.items.length) { 237 this.mediaData.currentIndex = 0; 238 this.isNextFag = true; 239 } 240 else { 241 this.isNextFag = true; 242 } 243 Log.debug(TAG, `updateMediaData start uri ${this.mediaData.currentUri} items.length ${this.items.length} 244 ${JSON.stringify(this.items)}`); 245 if (this.mediaData.currentUri != '') { 246 let isExist = false; 247 for (let i = 0; i < this.items.length; i++) { 248 let uri = this.items[i].uri; 249 if (uri == this.mediaData.currentUri) { 250 this.mediaData.currentIndex = i; 251 isExist = true; 252 } 253 } 254 if (!isExist) { 255 if (this.mediaData.isShowAlbum && (this.items.length !== 0) && (this.mediaData.currentIndex < this.items.length)) { 256 let item = this.items[this.mediaData.currentIndex]; 257 this.mediaData.currentUri = item.uri; 258 this.isUpdate = true; 259 } else { 260 this.mediaData.currentUri = ''; 261 } 262 if (this.items.length == 0) { 263 this.mediaData.currentUri = ''; 264 } 265 } 266 } else { 267 if (this.mediaData.isShowAlbum && (this.items.length !== 0) && 268 (this.mediaData.currentIndex < this.items.length)) { 269 let item = this.items[this.mediaData.currentIndex]; 270 this.mediaData.currentUri = item.uri; 271 } else { 272 this.mediaData.currentUri = ''; 273 } 274 } 275 Log.debug(TAG, `updateMediaData end! ${this.mediaData.currentIndex} uri ${this.mediaData.currentUri}`); 276 } 277 278 getUpdateTag(): boolean { 279 return this.isUpdate; 280 } 281 282 setUpdateTag(isUpdate: boolean): void { 283 this.isUpdate = isUpdate; 284 } 285 286 getCurrentItem(): userFileManager.FileAsset { 287 if ((this.mediaData.currentIndex < this.items.length) && 288 (this.mediaData.currentUri != '')) { 289 return this.items[this.mediaData.currentIndex]; 290 } else { 291 return null; 292 } 293 } 294 295 getCurrentAlbumName(): string { 296 return this.mediaData.displayName; 297 } 298 299 getCurrentIndex(): number { 300 return this.mediaData.currentIndex; 301 } 302 303 getIsShowAlbumName(): boolean { 304 let isShowAlbum: boolean = this.mediaData.isShowAlbum == 1; 305 let isShowName: boolean = Boolean(AppStorage.Get(Constants.FROM_PLAYBACK_ISSHOWNAME)); 306 Log.info(TAG, `getIsShowAlbumName isShowAlbum: ${isShowAlbum} isShowName: ${isShowName}`); 307 return isShowAlbum && isShowName; 308 } 309 310 getIntervalTime(): number { 311 Log.debug(TAG, `getIntervalTime time ${this.mediaData.intervalTime}`); 312 return this.mediaData.intervalTime; 313 } 314 315 setNextIndex(): void { 316 Log.debug(TAG, `setNextIndex start old index ${this.mediaData.currentIndex} flag ${this.isNextFag}`); 317 // this.mediaData.isShowAlbumName == false means select a photo instead of a album 318 if (this.isNextFag && this.mediaData.isShowAlbum) { 319 let index = this.mediaData.currentIndex; 320 if ((this.items.length != 0) && (index < this.items.length - 1)) { 321 index = index + 1; 322 } else { 323 index = 0; 324 } 325 this.mediaData.currentIndex = index; 326 if (this.items.length >= 1) { 327 let item = this.items[index]; 328 this.mediaData.currentUri = item.uri; 329 } else { 330 this.mediaData.currentUri = ''; 331 } 332 } 333 Log.debug(TAG, `setNextIndex index ${this.mediaData.currentIndex} uri ${this.mediaData.currentUri}`); 334 this.saveData(); 335 Log.debug(TAG, 'setNextIndex end!'); 336 } 337 338 getMediaData(): MediaData { 339 return this.mediaData; 340 } 341 342 async openCurrentFd(): Promise<number> { 343 let fileAsset = this.getCurrentItem(); 344 Log.info(TAG, `openCurrentFd uri: ${this.mediaData.currentUri}`); 345 let fd = (fileAsset != null) ? await this.mediaModel.openAsset('R', fileAsset) : -1; 346 Log.info(TAG, `openCurrentFd the fd: ${fd}`); 347 return fd; 348 } 349 350 getCurrentFd(): number { 351 return this.fd; 352 } 353 354 async closeFd(): Promise<void> { 355 Log.info(TAG, `close the fd: ${this.fd}`); 356 let fileAsset = this.getCurrentItem(); 357 if (fileAsset != null && this.fd != -1) { 358 await this.mediaModel.closeAsset(this.fd, fileAsset); 359 this.fd = -1; 360 } 361 } 362 363 async loadData(): Promise<void> { 364 Log.debug(TAG, 'loadData start!'); 365 this.items = await this.getItems(this.mediaData.albumUri); 366 if (this.items == null) { 367 this.items = []; 368 } 369 Log.info(TAG, `get album objects: Name:${this.mediaData.albumName} length: ${this.items.length}`); 370 await this.saveData(); 371 Log.debug(TAG, 'loadData end!'); 372 } 373 374 async getItems(albumUri?: string, startIndex?: number, count?: number, filterMediaType?: string): 375 Promise<Array<userFileManager.FileAsset>> { 376 let result: Array<userFileManager.FileAsset> = null; 377 378 // Get from target album if albumUri is not undefined, otherwise getAllObject 379 if (albumUri) { 380 let album: userFileManager.Album = await UserFileManagerAccess.getInstance().getAlbumByUri(albumUri); 381 let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType); 382 let fetchResult = await album.getPhotoAssets(fetchOpt); 383 result = await fetchResult.getAllObject(); 384 fetchResult.close(); 385 } else { 386 let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType); 387 Log.debug(TAG, `getMediaItem start ${JSON.stringify(fetchOpt)}`); 388 result = await UserFileManagerAccess.getInstance().getAllObject(fetchOpt); 389 } 390 return result; 391 } 392 393 private async getSystemAlbumName(id: string): Promise<string> { 394 try { 395 let album = await this.mediaModel.getAlbumByUri(id); 396 let result = await this.mediaModel.getAlbumName(album); 397 return result; 398 } catch (err) { 399 Log.error(TAG, `update the display name failed, form ${id} ` + err); 400 } 401 } 402}