1/* 2 * Copyright (C) 2022-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 mediaLibrary from '@ohos.multimedia.mediaLibrary'; 16import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; 17import uitest from '@ohos.UiTest'; 18import fs from '@ohos.file.fs'; 19 20let validImageExt = ['.jpg', '.png'] 21let validVideoExt = ['.mp4'] 22let validAudioExt = ['.mp3'] 23let validFileExt = ['.dat'] 24 25const presetsCount = { 26 ActsMediaLibraryAlbumTest: { albumsCount: 15, assetsCount: 27 }, 27 ActsMediaLibraryBaseTest: { albumsCount: 11, assetsCount: 14 }, 28 ActsMediaLibraryFavoriteTest: { albumsCount: 6, assetsCount: 32 }, 29 ActsMediaLibraryFileTest: { albumsCount: 6, assetsCount: 28 }, 30 ActsMediaLibraryFileAssetTest: { albumsCount: 27, assetsCount: 116 }, 31 ActsMediaLibraryFileKeyTest: { albumsCount: 2, assetsCount: 2 }, 32 ActsMediaLibraryFileResultTest: { albumsCount: 3, assetsCount: 112 }, 33 ActsMediaLibraryGetThumbnailTest: { albumsCount: 3, assetsCount: 3 }, 34 ActsMediaLibraryMediafetchoptionsTest: { albumsCount: 3, assetsCount: 8 }, 35 ActsMediaLibraryTrashJsTest: { albumsCount: 6, assetsCount: 24 }, 36}; 37 38const context = globalThis.abilityContext; 39const pathDir = context.filesDir; 40 41const IMAGE_TYPE = mediaLibrary.MediaType.IMAGE; 42const VIDEO_TYPE = mediaLibrary.MediaType.VIDEO; 43const AUDIO_TYPE = mediaLibrary.MediaType.AUDIO; 44const FILE_TYPE = mediaLibrary.MediaType.FILE; 45 46const FILEKEY = mediaLibrary.FileKey; 47const { RELATIVE_PATH, ALBUM_NAME, MEDIA_TYPE } = FILEKEY; 48 49const sleep = async function sleep(times) { 50 if (!times) { 51 times = 10; 52 } 53 await new Promise((res) => setTimeout(res, times)); 54}; 55 56const allFetchOp = function(others) { 57 if (!others) { 58 others = {}; 59 } 60 return { 61 selections: '', 62 selectionArgs: [], 63 ...others, 64 }; 65}; 66 67const fetchOps = function(testNum, path, type, others) { 68 if (!others) { 69 others = {}; 70 } 71 let ops = { 72 selections: FILEKEY.RELATIVE_PATH + '= ? AND ' + FILEKEY.MEDIA_TYPE + '=?', 73 selectionArgs: [path, type.toString()], 74 ...others, 75 }; 76 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 77 return ops; 78}; 79const nameFetchOps = function(testNum, path, display_name, type) { 80 let ops = { 81 selections: FILEKEY.RELATIVE_PATH + '= ? AND ' + FILEKEY.DISPLAY_NAME + '= ? AND ' + FILEKEY.MEDIA_TYPE + '=?', 82 selectionArgs: [path, display_name, type.toString()], 83 }; 84 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 85 return ops; 86}; 87 88const idFetchOps = function(testNum, albumId) { 89 let ops = { 90 selections: FILEKEY.ALBUM_ID + '= ?', 91 selectionArgs: [albumId + ''], 92 }; 93 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 94 return ops; 95}; 96 97const fileIdFetchOps = function(testNum, id) { 98 let ops = { 99 selections: FILEKEY.ID + '= ?', 100 selectionArgs: [id + ''], 101 }; 102 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 103 return ops; 104}; 105 106const albumFetchOps = function(testNum, albumName, others) { 107 let ops = { 108 selections: ALBUM_NAME + '= ?', 109 selectionArgs: [albumName], 110 ...others, 111 }; 112 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 113 return ops; 114}; 115 116// albums of two resource types 117const albumTwoTypesFetchOps = function(testNum, paths, albumName, types, others) { 118 if (!others) { 119 others = { order: FILEKEY.DATE_ADDED + ' DESC' }; 120 } 121 try { 122 let ops = { 123 selections: 124 '(' + 125 RELATIVE_PATH + 126 '= ? or ' + 127 RELATIVE_PATH + 128 '= ? ) AND ' + 129 ALBUM_NAME + 130 '= ? AND (' + 131 MEDIA_TYPE + 132 '= ? or ' + 133 MEDIA_TYPE + 134 '= ?)', 135 selectionArgs: [paths[0], paths[1], albumName, types[0].toString(), types[1].toString()], 136 ...others, 137 }; 138 console.info(`${testNum}: fetchOps${JSON.stringify(ops)}`); 139 return ops; 140 } catch (error) { 141 console.info(`albumTwoTypesFetchOps :: error: ${error}`); 142 } 143}; 144 145// albums of three resource types 146const albumThreeTypesFetchOps = function(testNum, paths, albumName, types, others) { 147 if (!others) { 148 others = { order: FILEKEY.DATE_ADDED + ' DESC' }; 149 } 150 try { 151 let ops = { 152 selections: 153 '(' + 154 RELATIVE_PATH + 155 '= ? or ' + 156 RELATIVE_PATH + 157 '= ? or ' + 158 RELATIVE_PATH + 159 '= ? ) AND ' + 160 ALBUM_NAME + 161 '= ? AND (' + 162 MEDIA_TYPE + 163 '= ? or ' + 164 MEDIA_TYPE + 165 '= ? or ' + 166 MEDIA_TYPE + 167 '= ?)', 168 selectionArgs: [ 169 paths[0], 170 paths[1], 171 paths[2], 172 albumName, 173 types[0].toString(), 174 types[1].toString(), 175 types[2].toString(), 176 ], 177 ...others, 178 }; 179 console.info(`${testNum}: fetchOps ${JSON.stringify(ops)}`); 180 return ops; 181 } catch (error) { 182 console.info(`albumThreeTypesFetchOps :: error: ${error}`); 183 } 184}; 185 186const fileFetchOption = function(testNum, selections, selectionArgs) { 187 let ops = { 188 selections: selections, 189 selectionArgs: selectionArgs, 190 }; 191 console.info(`${testNum} fetchOps: ${JSON.stringify(ops)}`); 192 return ops; 193} 194 195const checkPresetsAssets = async function(media, hapName) { 196 console.info('checkPresetsAssets start'); 197 let albumList = await media.getAlbums(allFetchOp()); 198 let albumsCount = albumList.length; 199 let fetchFileResult = await media.getFileAssets(allFetchOp()); 200 let assetsCount = await fetchFileResult.getCount(); 201 let presetsassetsCount = presetsCount[hapName].assetsCount; 202 let presetsalbumsCount = presetsCount[hapName].albumsCount; 203 if (assetsCount !== presetsCount[hapName].assetsCount || albumsCount !== presetsCount[hapName].albumsCount) { 204 console.info(`${hapName} checkPresetsAssets failed; 205 assetsCount : presetsassetsCount = ${assetsCount} : ${presetsassetsCount} 206 albumsCount : presetsalbumsCount = ${albumsCount} : ${presetsalbumsCount}`); 207 fetchFileResult.close(); 208 } else { 209 console.info(`${hapName} checkPresetsAssets passed`); 210 fetchFileResult.close(); 211 } 212}; 213 214const checkAssetsCount = async function(testNum, fetchFileResult, expectCount) { 215 if (!fetchFileResult) { 216 console.info(`${testNum}:: fetchFileResult error:`); 217 return false; 218 } 219 let count = await fetchFileResult.getCount(); 220 if (count !== expectCount) { 221 console.info(`${testNum}:: count:expectCount - ${count} : ${expectCount}`); 222 } 223 return count === expectCount; 224}; 225 226const checkAlbumsCount = function(testNum, albumList, expectCount) { 227 if (!albumList || !Array.isArray(albumList)) { 228 console.info(`${testNum}:: albumList error:`); 229 return false; 230 } 231 let albumsCount = albumList.length; 232 if (albumsCount !== expectCount) { 233 console.info(`${testNum}:: albumsCount: expectCount - ${albumsCount} : ${expectCount}`); 234 } 235 return albumsCount === expectCount; 236}; 237 238const getPermission = async function(name, context) { 239 if (!name) { 240 name = 'ohos.acts.multimedia.mediaLibrary'; 241 } 242 243 try { 244 console.info('getPermission start: ' + name); 245 let isGetPermission = false; 246 let permissions = ['ohos.permission.MEDIA_LOCATION', 'ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA']; 247 let atManager = abilityAccessCtrl.createAtManager(); 248 atManager.requestPermissionsFromUser(context, permissions, (err, result) => { 249 if (err) { 250 console.info('getPermission failed: ' + JSON.stringify(err)); 251 } else { 252 console.info('getPermission suc: ' + JSON.stringify(result)); 253 isGetPermission = true; 254 } 255 }); 256 257 let driver = uitest.Driver.create(); 258 await sleep(500); 259 for (let i = 0; i < 10; i++) { 260 if (isGetPermission) { 261 break; 262 } 263 await sleep(500); 264 let button = await driver.findComponent(uitest.ON.text('允许')); 265 if (button !== undefined) { 266 await button.click(); 267 } 268 } 269 console.info('getPermission end'); 270 } catch (error) { 271 console.info('getPermission error: ' + error); 272 } 273}; 274 275const MODIFY_ERROR_CODE_01 = '-1000'; 276 277const isNum = function(value) { 278 return typeof value === 'number' && !isNaN(value); 279}; 280 281const getFileNameArray = async function () { 282 try{ 283 let listFileOption = { 284 recursion: true, 285 listNum: 0, 286 filter: { 287 suffix: [] 288 } 289 } 290 listFileOption.filter.suffix = validImageExt.concat(validVideoExt).concat(validAudioExt).concat(validFileExt); 291 let nameArray = await fs.listFile(pathDir, listFileOption); 292 console.info('getFileNameArray successfully nameArray: ' + nameArray); 293 return nameArray; 294 } catch (err) { 295 console.info('getFileNameArray failed: ' + err); 296 } 297}; 298 299const pushCreateAsset = async function (media, context, targetAssetNames, directoryTypes, targetDirs) { 300 console.info('pushCreateAsset start'); 301 let pathDir = context.filesDir; 302 let successNum = 0; 303 try { 304 console.info('pushCreateAsset targetAssetNames: ' + targetAssetNames); 305 let mediaType; 306 let path; 307 let sourceFileNames = await getFileNameArray(); 308 console.info('pushCreateAsset sourceFileNames: ' + sourceFileNames); 309 for (let i = 0; i < sourceFileNames.length; i++) { 310 let fileName = sourceFileNames[i]; 311 let sourceExtension = fileName.split('.')[1]; 312 let sourceFilePath = pathDir + fileName; 313 for (let j = 0; j < targetAssetNames.length; j++) { 314 path = await media.getPublicDirectory(directoryTypes[j]); 315 let targetAssetName = targetAssetNames[j]; 316 let targetAssetExtension = targetAssetName.split('.')[1]; 317 if (sourceExtension === targetAssetExtension) { 318 if (validImageExt.includes(('.' + targetAssetExtension))) { 319 mediaType = IMAGE_TYPE 320 } else if (validVideoExt.includes(('.' + targetAssetExtension))) { 321 mediaType = VIDEO_TYPE 322 } else if (validAudioExt.includes(('.' + targetAssetExtension))) { 323 mediaType = AUDIO_TYPE 324 } else { 325 mediaType = FILE_TYPE 326 } 327 let asset = await media.createAsset(mediaType, targetAssetName, path + targetDirs[j]); 328 await IOfunc(sourceFilePath, asset); 329 successNum++; 330 } 331 } 332 } 333 if (successNum !== targetAssetNames.length) { 334 console.info('pushCreateAsset failed fileNumber insufficient, : ' + successNum); 335 return; 336 } 337 console.info('pushCreateAsset successfully fileNumber: ' + successNum); 338 } catch (err) { 339 console.info('pushCreateAsset push resource failed: ' + err) 340 return; 341 } 342}; 343 344const IOfunc = async function (filePath, targetFile) { 345 try { 346 let srcFile = fs.openSync(filePath, fs.OpenMode.READ_ONLY | fs.OpenMode.CREATE); 347 let destFileFd = await targetFile.open('rw'); 348 let bufSize = 4096; 349 let readSize = 0; 350 let buf = new ArrayBuffer(bufSize); 351 let readOptions = { 352 offset: readSize, 353 length: bufSize 354 }; 355 let readLen = fs.readSync(srcFile.fd, buf, readOptions); 356 while (readLen > 0) { 357 readSize += readLen; 358 fs.writeSync(destFileFd, buf, {length: readLen}); 359 readOptions.offset = readSize; 360 readLen = fs.readSync(srcFile.fd, buf, readOptions); 361 } 362 fs.closeSync(srcFile); 363 await targetFile.close(destFileFd); 364 } catch (e) { 365 console.log('FileIO_fs_filerw_test has failed for ' + e.message + ', code: ' + e.code); 366 } 367}; 368 369export { 370 getPermission, 371 IMAGE_TYPE, 372 VIDEO_TYPE, 373 AUDIO_TYPE, 374 FILE_TYPE, 375 FILEKEY, 376 sleep, 377 allFetchOp, 378 fetchOps, 379 nameFetchOps, 380 idFetchOps, 381 albumFetchOps, 382 fileFetchOption, 383 albumTwoTypesFetchOps, 384 albumThreeTypesFetchOps, 385 checkPresetsAssets, 386 checkAssetsCount, 387 checkAlbumsCount, 388 MODIFY_ERROR_CODE_01, 389 isNum, 390 fileIdFetchOps, 391 pushCreateAsset, 392}; 393