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