1/* 2 * Copyright (C) 2023-2024 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 photoAccessHelper from '@ohos.file.photoAccessHelper'; 17import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; 18import bundleManager from '@ohos.bundle.bundleManager'; 19import dataSharePredicates from '@ohos.data.dataSharePredicates'; 20import abilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'; 21import fs, { ListFileOptions } from '@ohos.file.fs'; 22import fileuri from "@ohos.file.fileuri"; 23 24const delegator = abilityDelegatorRegistry.getAbilityDelegator(); 25const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(globalThis.abilityContext); 26const photoType = photoAccessHelper.PhotoType; 27const photoKeys = photoAccessHelper.PhotoKeys; 28const albumKeys = photoAccessHelper.AlbumKeys; 29const albumType = photoAccessHelper.AlbumType; 30const albumSubtype = photoAccessHelper.AlbumSubtype; 31const DEFAULT_SLEEP_TIME = 10; 32 33const context = globalThis.abilityContext; 34const pathDir = context.filesDir; 35 36let validImageExt = ['.jpg'] 37let validVideoExt = ['.mp4'] 38 39export async function sleep(times = DEFAULT_SLEEP_TIME) : Promise<void> { 40 await new Promise(res => setTimeout(res, times)); 41}; 42 43export function fetchAllOption() : photoAccessHelper.FetchOptions { 44 const predicates = new dataSharePredicates.DataSharePredicates(); 45 const ops : photoAccessHelper.FetchOptions = { 46 fetchColumns: [], 47 predicates: predicates 48 }; 49 return ops; 50}; 51 52export function fetchOption(testNum, key, value) : photoAccessHelper.FetchOptions { 53 const predicates = new dataSharePredicates.DataSharePredicates(); 54 predicates.equalTo(key, value); 55 const ops : photoAccessHelper.FetchOptions = { 56 fetchColumns: [], 57 predicates: predicates 58 }; 59 console.info(`${testNum} queryOps: ${key} = ${value}`); 60 return ops; 61}; 62 63export function albumFetchOption(testNum, key, value) : photoAccessHelper.FetchOptions { 64 const predicates = new dataSharePredicates.DataSharePredicates(); 65 predicates.equalTo(key, value); 66 const ops : photoAccessHelper.FetchOptions = { 67 fetchColumns: [], 68 predicates: predicates 69 }; 70 console.info(`${testNum} queryOps: ${key} = ${value}`); 71 return ops; 72}; 73 74export function photoFetchOption(testNum, key, value) : photoAccessHelper.FetchOptions { 75 const predicates = new dataSharePredicates.DataSharePredicates(); 76 predicates.equalTo(key, value); 77 const ops : photoAccessHelper.FetchOptions = { 78 fetchColumns: [ 79 photoKeys.URI, 80 photoKeys.PHOTO_TYPE, 81 photoKeys.DISPLAY_NAME, 82 photoKeys.DATE_ADDED, 83 photoKeys.DATE_MODIFIED, 84 photoKeys.DURATION, 85 photoKeys.WIDTH, 86 photoKeys.HEIGHT, 87 photoKeys.DATE_TAKEN, 88 photoKeys.ORIENTATION, 89 photoKeys.FAVORITE, 90 photoKeys.SIZE, 91 photoKeys.TITLE, 92 photoKeys.POSITION, 93 photoKeys.DATE_TRASHED, 94 photoKeys.HIDDEN, 95 photoKeys.CAMERA_SHOT_KEY, 96 photoKeys.USER_COMMENT, 97 'all_exif', 98 ], 99 predicates: predicates 100 }; 101 console.info(`${testNum} queryOps: ${key} = ${value}`); 102 return ops; 103}; 104 105export async function getPermission(name = 'ohos.acts.multimedia.photoaccess') : Promise<void> { 106 try { 107 console.info('getPermission start', name); 108 let permissionState = new Map(); 109 const permissions = [ 110 'ohos.permission.MEDIA_LOCATION', 111 'ohos.permission.READ_IMAGEVIDEO', 112 'ohos.permission.WRITE_IMAGEVIDEO', 113 ]; 114 115 const atManager = abilityAccessCtrl.createAtManager(); 116 const appFlags = bundleManager.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT; 117 const userId = 100; 118 const appInfo = await bundleManager.getApplicationInfo(name, appFlags, userId); 119 const tokenID = appInfo.accessTokenId; 120 for (const permission of permissions) { 121 console.info('getPermission permission: ' + permission); 122 try { 123 await atManager.grantUserGrantedPermission(tokenID, permission, 1); 124 } catch (error) { 125 console.info(`getPermission ${permission} failed`); 126 } 127 permissionState.set(permission, await atManager.verifyAccessToken(tokenID, permission)); 128 } 129 permissionState.forEach((value, key, map) => { 130 if (value !== 0) { 131 console.info(`getPermission failed; permission: ${key}, state: ${value}`); 132 } 133 }); 134 console.info('getPermission end'); 135 } catch (error) { 136 console.info(`getPermission failed, error: ${error}`); 137 } 138}; 139 140export function isNum(value) : boolean { 141 return typeof value === 'number' && !isNaN(value); 142}; 143 144export function getAssetId(uri) : string { 145 const tag = 'Photo/'; 146 const index = uri.indexOf(tag); 147 let str = uri.substring(index + tag.length); 148 console.info(`getAssetId str: ${str}`); 149 return str; 150} 151 152export function getAlbumId(uri) : string { 153 const index = uri.lastIndexOf('/'); 154 let str = uri.substring(index + 1); 155 console.info(`getAlbumId str: ${str}`); 156 return str; 157} 158 159export function genRadomStr(len: number) : string { 160 const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 161 let randomStr = ''; 162 for (let i = 0; i < len; i++) { 163 randomStr += chars.charAt(Math.floor(Math.random() * chars.length)); 164 } 165 return randomStr; 166} 167 168export async function createUserAlbum(testNum, albumName) : Promise<photoAccessHelper.Album> { 169 console.info(`${testNum} createUserAlbum albumName: ${albumName}`); 170 let album: photoAccessHelper.Album; 171 try { 172 const helper = photoAccessHelper.getPhotoAccessHelper(globalThis.abilityContext); 173 album = await helper.createAlbum(albumName); 174 console.info(`${testNum} createUserAlbum suc`); 175 } catch (error) { 176 console.info(`Failed to createUserAlbum! error: ${error}`); 177 throw error; 178 } 179 180 return new Promise((resolve, reject) => { 181 resolve(album); 182 }); 183} 184 185export async function getFileAsset(testNum, fetchOps) : Promise<photoAccessHelper.PhotoAsset> { 186 let asset: photoAccessHelper.PhotoAsset; 187 try { 188 const helper = photoAccessHelper.getPhotoAccessHelper(globalThis.abilityContext); 189 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset>; 190 fetchResult = await helper.getAssets(fetchOps); 191 console.info(`${testNum} getFileAsset fetchResult: ${fetchResult.getCount()}`); 192 asset = await fetchResult.getFirstObject(); 193 fetchResult.close(); 194 } catch (error) { 195 console.info(`${testNum} getFileAsset error: ${error}`); 196 throw error; 197 } 198 199 return new Promise((resolve, reject) => { 200 resolve(asset); 201 }); 202} 203 204export function getFileAssetFetchResult() : photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> { 205 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset>; 206 return fetchResult; 207} 208 209export function getAlbumFetchResult() : photoAccessHelper.FetchResult<photoAccessHelper.Album> { 210 let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album>; 211 return fetchResult; 212} 213 214export function checkUserAlbum(expect, testNum, album, expectedName, expectedCover) : void { 215 console.info(`${testNum} checkUserAlbum album.albumName: ${album.albumName}, expectedName: ${expectedName}`); 216 expect(album.albumType).assertEqual(albumType.USER); 217 expect(album.albumSubtype).assertEqual(albumSubtype.USER_GENERIC); 218 expect(album.albumName).assertEqual(expectedName); 219 if (expectedCover === '') { 220 expect(album.coverUri).assertEqual(''); 221 } else { 222 expect(album.coverUri).assertEqual(expectedCover); 223 } 224 expect(album.albumUri !== '').assertEqual(true); 225 expect(album.count).assertEqual(0); 226} 227 228export function checkSystemAlbum(expect, testNum, album, expectedSubType) : void { 229 try { 230 console.info(`${testNum} checkSystemAlbum expectedSubType: ${expectedSubType}`); 231 expect(album.albumType).assertEqual(albumType.SYSTEM); 232 expect(album.albumSubtype).assertEqual(expectedSubType); 233 expect(album.albumName).assertEqual(''); 234 expect(album.albumUri !== '').assertEqual(true); 235 } catch (error) { 236 console.info(`Failed to delete all user albums! error: ${error}`); 237 throw error; 238 } 239} 240 241export async function startAbility(bundleName: string, abilityName: string) : Promise<void> { 242 await delegator.executeShellCommand(`aa start -b ${bundleName} -a ${abilityName}`).then(result => { 243 console.info(`[picker] start abilityFinished: ${result}`); 244 }).catch(err => { 245 console.error(`[picker] start abilityFailed: ${err}`); 246 }); 247} 248 249export async function stopAbility(bundleName: string) : Promise<void> { 250 await delegator.executeShellCommand(`aa force-stop ${bundleName}`).then(result => { 251 console.info(`[picker] stop abilityFinished: ${result}`); 252 }).catch(err => { 253 console.error(`[picker] stop abilityFailed: ${err}`); 254 }); 255} 256 257export async function getFileNameArray() { 258 try{ 259 let listFileOption: ListFileOptions = { 260 recursion: true, 261 listNum: 0, 262 filter: { 263 suffix: [], 264 } 265 } 266 listFileOption.filter.suffix = validImageExt.concat(validVideoExt); 267 let nameArray = await fs.listFile(pathDir, listFileOption) 268 return nameArray; 269 } catch (err) { 270 console.info('getFileNameArray failed: ' + err); 271 } 272} 273 274export async function pushCreateAsset(names: Array<string>){ 275 console.info('pushCreateAsset start') 276 let successNum = 0; 277 try{ 278 console.info('pushCreateAsset name: ' + names) 279 let photoType: photoAccessHelper.PhotoType; 280 let resourceType: photoAccessHelper.ResourceType; 281 let fileNames: string[] = await getFileNameArray(); 282 console.info('pushCreateAsset rawFiles number: ' + fileNames.length); 283 for(let i = 0; i < fileNames.length; i++) { 284 let fileName = fileNames[i]; 285 let filePath = pathDir + '/' + fileName; 286 let fileUri = fileuri.getUriFromPath(filePath); 287 let rawExtension: string = fileName.split('.')[1]; 288 for (let j = 0; j < names.length; j++) { 289 let name = names[j]; 290 let extension: string = name.split('.')[1]; 291 if (rawExtension === extension) { 292 let options: photoAccessHelper.CreateOptions = { 293 title: name.split('.')[0] 294 } 295 if (validImageExt.includes(('.' + extension))) { 296 photoType = photoAccessHelper.PhotoType.IMAGE; 297 resourceType = photoAccessHelper.ResourceType.IMAGE_RESOURCE; 298 } else { 299 photoType = photoAccessHelper.PhotoType.VIDEO; 300 resourceType = photoAccessHelper.ResourceType.VIDEO_RESOURCE; 301 } 302 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createAssetRequest(globalThis.abilityContext, photoType, extension, options); 303 assetChangeRequest.addResource(resourceType, fileUri); 304 await phAccessHelper.applyChanges(assetChangeRequest); 305 successNum++; 306 } 307 } 308 } 309 console.info('Push_createAsset successfully fileNumber: ' + successNum); 310 }catch(err){ 311 console.info('Push_createAsset push resource failed: ' + err) 312 return; 313 } 314} 315 316export { 317 photoType, 318 photoKeys, 319 albumKeys, 320 albumType, 321 albumSubtype, 322};