Files
2026-08-11 17:41:36 +08:00

10586 lines
414 KiB
Plaintext

import Want from '@ohos.app.ability.Want';
import common from '@ohos.app.ability.common';
import wantConstant from '@ohos.app.ability.wantConstant';
import buffer from '@ohos.buffer';
import uniformTypeDescriptor from '@ohos.data.uniformTypeDescriptor';
import deviceInfo from '@ohos.deviceInfo';
import fs from '@ohos.file.fs';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import inputMethod from '@ohos.inputMethod';
import media from '@ohos.multimedia.media';
import connection from '@ohos.net.connection';
import webSocket from '@ohos.net.webSocket';
import pasteboard from '@ohos.pasteboard';
import cryptoFramework from '@ohos.security.cryptoFramework';
import call from '@ohos.telephony.call';
import radio from '@ohos.telephony.radio';
import uri from '@ohos.uri';
import util from '@ohos.util';
import webview from '@ohos.web.webview';
import zlib from '@ohos.zlib';
import { BusinessError as BusinessError1 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError10 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError11 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError12 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError13 } from '@ohos.base';
import { BusinessError as BusinessError14 } from '@ohos.base';
import { BusinessError as BusinessError2 } from '@ohos.base';
import { BusinessError as BusinessError3 } from '@ohos.base';
import { BusinessError as BusinessError4 } from '@ohos.base';
import { BusinessError as BusinessError5 } from '@ohos.base';
import { BusinessError as BusinessError6 } from '@ohos.base';
import { BusinessError as BusinessError7 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError8 } from '@kit.BasicServicesKit';
import { BusinessError as BusinessError9 } from '@kit.BasicServicesKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { CompressorResponseCode, CompressorResponse, VideoCompressor, CompressQuality } from '@ohos/videocompressor';
import { Emitter as Emitter1, onNativePageReady } from "@dcloudio/uni-mp-sdk";
import { Emitter as Emitter2, getCurrentMP as getCurrentMP1 } from "@dcloudio/uni-mp-sdk";
import { Emitter as Emitter5, getCurrentMP as getCurrentMP5 } from "@dcloudio/uni-mp-sdk";
import { Emitter, getCurrentMP } from "@dcloudio/uni-mp-sdk";
import Hash from '@ohos.file.hash';
import I18n from '@ohos.i18n';
import I18n1 from '@ohos.i18n';
import I18n2 from '@ohos.i18n';
import { ListFileOptions } from '@ohos.file.fs';
import { ReadOptions as ReadOptions2 } from '@ohos.file.fs';
import { ReadOptions } from '@ohos.file.fs';
import { UTSHarmony } from "@dcloudio/uni-mp-sdk";
import { UTSObject, UniError, IUniError, string, ApiError, UniProvider, UTSJSONObject, AsyncApiSuccessResult, AsyncApiResult, ApiOptions, ProtocolOptions, defineAsyncApi, ApiExecutor, defineSyncApi, getUniProviders, defineTaskApi, getUniProvider } from "./shared";
import Want1 from '@ohos.app.ability.Want';
import { abilityAccessCtrl } from '@kit.AbilityKit';
import { access } from '@kit.ConnectivityKit';
import { audio as audio1 } from '@kit.AudioKit';
import { audio } from '@kit.AudioKit';
import { avSession } from '@kit.AVSessionKit';
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import buffer1 from '@ohos.buffer';
import { bundleManager } from '@kit.AbilityKit';
import bundleManager1 from '@ohos.bundle.bundleManager';
import bundleManager2 from '@ohos.bundle.bundleManager';
import { camera as camera1 } from '@kit.CameraKit';
import { camera } from '@kit.CameraKit';
import { cameraPicker as cameraPicker1 } from '@kit.CameraKit';
import { cameraPicker } from '@kit.CameraKit';
import common1 from '@ohos.app.ability.common';
import common2 from '@ohos.app.ability.common';
import common3 from '@ohos.app.ability.common';
import common4 from '@ohos.app.ability.common';
import { contact } from '@kit.ContactsKit';
import cryptoFramework1 from '@ohos.security.cryptoFramework';
import dataPreferences from '@ohos.data.preferences';
import deviceInfo1 from '@ohos.deviceInfo';
import { display } from '@kit.ArkUI';
import { fileIo as fileIo1 } from '@kit.CoreFileKit';
import { fileIo as fileIo2 } from '@kit.CoreFileKit';
import { fileIo as fileIo3 } from '@kit.CoreFileKit';
import { fileIo as fileIo4 } from '@kit.CoreFileKit';
import { fileIo as fs5 } from '@kit.CoreFileKit';
import { fileIo } from '@kit.CoreFileKit';
import fileUri from '@ohos.file.fileuri';
import fileUri1 from '@ohos.file.fileuri';
import fs1 from '@ohos.file.fs';
import fs2, { ReadTextOptions } from '@ohos.file.fs';
import fs3, { ListFileOptions as ListFileOptions1, WriteOptions as OHWriteOptions, ReadOptions as ReadOptions1, ReadTextOptions as ReadTextOptions1 } from '@ohos.file.fs';
import fs4 from '@ohos.file.fs';
import fs6 from '@ohos.file.fs';
import fs7 from '@ohos.file.fs';
import fs8 from '@ohos.file.fs';
import { geoLocationManager } from '@kit.LocationKit';
import { getCurrentMP as getCurrentMP4 } from "@dcloudio/uni-mp-sdk";
import { getDeviceId } from "@dcloudio/uni-mp-sdk";
import { getEnv as getEnv1, getRealPath as getRealPath1 } from "@dcloudio/uni-mp-sdk";
import { getEnv as getEnv2, getRealPath as runtimeGetRealPath } from "@dcloudio/uni-mp-sdk";
import { getEnv as getEnv3 } from "@dcloudio/uni-mp-sdk";
import { getEnv as getEnv4 } from "@dcloudio/uni-mp-sdk";
import { getEnv as getEnv5, Emitter as Emitter4, getCurrentMP as getCurrentMP3 } from "@dcloudio/uni-mp-sdk";
import { getEnv, getRealPath } from "@dcloudio/uni-mp-sdk";
import { getOSRuntime as getOSRuntime1, onNativePageReady as onNativePageReady2 } from "@dcloudio/uni-mp-sdk";
import { getOSRuntime, onNativePageReady as onNativePageReady1 } from "@dcloudio/uni-mp-sdk";
import { getRealPath as getRealPath2 } from "@dcloudio/uni-mp-sdk";
import { getRealPath as getRealPath3 } from "@dcloudio/uni-mp-sdk";
import { getRealPath as getRealPath4 } from "@dcloudio/uni-mp-sdk";
import { getRealPath as getRealPath5, Emitter as Emitter3, getCurrentMP as getCurrentMP2 } from "@dcloudio/uni-mp-sdk";
import { getResourceStr } from "@dcloudio/uni-mp-sdk";
import { getWindowInfo as internalGetWindowInfo, getDeviceId as getDeviceId1 } from "@dcloudio/uni-mp-sdk";
import harmonyUrl from '@ohos.url';
import harmonyUrl1 from '@ohos.url';
import harmonyWindow from '@ohos.window';
import { http } from '@kit.NetworkKit';
import http1 from '@ohos.net.http';
import http2 from '@ohos.net.http';
import http3 from '@ohos.net.http';
import { image } from '@kit.ImageKit';
import image1 from '@ohos.multimedia.image';
import { media as media1 } from '@kit.MediaKit';
import { media as media2 } from '@kit.MediaKit';
import media3 from '@ohos.multimedia.media';
import media4 from '@ohos.multimedia.media';
import { notificationManager } from '@kit.NotificationKit';
import photoAccessHelper1 from '@ohos.file.photoAccessHelper';
import photoAccessHelper2 from '@ohos.file.photoAccessHelper';
import photoAccessHelper3 from '@ohos.file.photoAccessHelper';
import photoAccessHelper4 from '@ohos.file.photoAccessHelper';
import photoAccessHelper5 from '@ohos.file.photoAccessHelper';
import { picker, fileIo as fileIo5 } from '@kit.CoreFileKit';
import { promptAction as promptAction2 } from '@kit.ArkUI';
import { promptAction as promptAction3 } from '@kit.ArkUI';
import { promptAction as promptAction4 } from '@kit.ArkUI';
import { promptAction } from '@kit.ArkUI';
import promptAction1 from '@ohos.promptAction';
import promptAction5 from '@ohos.promptAction';
import { scanCore, scanBarcode } from '@kit.ScanKit';
import { startPullDownRefresh as internalStartPullDownRefresh, stopPullDownRefresh as internalStopPullDownRefresh } from "@dcloudio/uni-mp-sdk";
import { systemShare } from '@kit.ShareKit';
import { uni } from "@dcloudio/uni-mp-sdk";
import { uniformTypeDescriptor as uniformTypeDescriptor1 } from '@kit.ArkData';
import { userAuth } from '@kit.UserAuthenticationKit';
import util1 from '@ohos.util';
import { wantAgent } from '@kit.AbilityKit';
import { wifiManager } from '@kit.ConnectivityKit';
import { window as window1 } from '@kit.ArkUI';
import { window as window2 } from '@kit.ArkUI';
import { window } from '@kit.ArkUI';
type AddPhoneContact = (options: AddPhoneContactOptions) => void;
class AddPhoneContactSuccess extends UTSObject {
}
type AddPhoneContactSuccessCallback = (result: AddPhoneContactSuccess) => void;
type AddPhoneContactFail = UniError;
type AddPhoneContactFailCallback = (result: AddPhoneContactFail) => void;
type AddPhoneContactComplete = Object;
type AddPhoneContactCompleteCallback = (result: AddPhoneContactComplete) => void;
class AddPhoneContactOptions extends UTSObject {
photoFilePath: string | null = null;
nickName: string | null = null;
lastName: string | null = null;
middleName: string | null = null;
firstName: string | null = null;
remark: string | null = null;
mobilePhoneNumber: string | null = null;
weChatNumber: string | null = null;
addressCountry: string | null = null;
addressState: string | null = null;
addressCity: string | null = null;
addressStreet: string | null = null;
addressPostalCode: string | null = null;
organization: string | null = null;
title: string | null = null;
workFaxNumber: string | null = null;
workPhoneNumber: string | null = null;
hostNumber: string | null = null;
email: string | null = null;
url: string | null = null;
workAddressCountry: string | null = null;
workAddressState: string | null = null;
workAddressCity: string | null = null;
workAddressStreet: string | null = null;
workAddressPostalCode: string | null = null;
homeFaxNumber: string | null = null;
homePhoneNumber: string | null = null;
homeAddressCountry: string | null = null;
homeAddressState: string | null = null;
homeAddressCity: string | null = null;
homeAddressStreet: string | null = null;
homeAddressPostalCode: string | null = null;
success: AddPhoneContactSuccessCallback | null = null;
fail: AddPhoneContactFailCallback | null = null;
complete: AddPhoneContactCompleteCallback | null = null;
}
type StartSoterAuthentication = (options: StartSoterAuthenticationOptions) => void;
type SoterAuthMode = 'fingerPrint' | 'facial' | 'speech';
class StartSoterAuthenticationSuccess extends UTSObject {
errCode!: number;
authMode!: SoterAuthMode;
resultJSON: string | null = null;
resultJSONSignature: string | null = null;
errMsg!: string;
}
type StartSoterAuthenticationSuccessCallback = (result: StartSoterAuthenticationSuccess) => void;
type StartSoterAuthenticationFail = UniError;
type StartSoterAuthenticationFailCallback = (result: StartSoterAuthenticationFail) => void;
type StartSoterAuthenticationComplete = Object;
type StartSoterAuthenticationCompleteCallback = (result: StartSoterAuthenticationComplete) => void;
class StartSoterAuthenticationOptions extends UTSObject {
requestAuthModes!: SoterAuthMode[];
challenge: string | null = null;
authContent: string | null = null;
success: StartSoterAuthenticationSuccessCallback | null = null;
fail: StartSoterAuthenticationFailCallback | null = null;
complete: StartSoterAuthenticationCompleteCallback | null = null;
}
type CheckIsSupportSoterAuthentication = (options: CheckIsSupportSoterAuthenticationOptions) => void;
class CheckIsSupportSoterAuthenticationSuccess extends UTSObject {
supportMode!: SoterAuthMode[];
errMsg!: string;
}
type CheckIsSupportSoterAuthenticationSuccessCallback = (result: CheckIsSupportSoterAuthenticationSuccess) => void;
type CheckIsSupportSoterAuthenticationFail = UniError;
type CheckIsSupportSoterAuthenticationFailCallback = (result: CheckIsSupportSoterAuthenticationFail) => void;
type CheckIsSupportSoterAuthenticationComplete = Object;
type CheckIsSupportSoterAuthenticationCompleteCallback = (result: CheckIsSupportSoterAuthenticationComplete) => void;
class CheckIsSupportSoterAuthenticationOptions extends UTSObject {
success: CheckIsSupportSoterAuthenticationSuccessCallback | null = null;
fail: CheckIsSupportSoterAuthenticationFailCallback | null = null;
complete: CheckIsSupportSoterAuthenticationCompleteCallback | null = null;
}
type CheckIsSoterEnrolledInDevice = (options: CheckIsSoterEnrolledInDeviceOptions) => void;
class CheckIsSoterEnrolledInDeviceSuccess extends UTSObject {
isEnrolled!: boolean;
errMsg!: string;
}
type CheckIsSoterEnrolledInDeviceSuccessCallback = (result: CheckIsSoterEnrolledInDeviceSuccess) => void;
type CheckIsSoterEnrolledInDeviceFail = UniError;
type CheckIsSoterEnrolledInDeviceFailCallback = (result: CheckIsSoterEnrolledInDeviceFail) => void;
type CheckIsSoterEnrolledInDeviceComplete = Object;
type CheckIsSoterEnrolledInDeviceCompleteCallback = (result: CheckIsSoterEnrolledInDeviceComplete) => void;
class CheckIsSoterEnrolledInDeviceOptions extends UTSObject {
checkAuthMode!: SoterAuthMode;
success: CheckIsSoterEnrolledInDeviceSuccessCallback | null = null;
fail: CheckIsSoterEnrolledInDeviceFailCallback | null = null;
complete: CheckIsSoterEnrolledInDeviceCompleteCallback | null = null;
}
type ChooseMediaErrorCode = 1101001 | 1101005 | 1101006 | 1101008;
interface IChooseMediaError extends IUniError {
errCode: ChooseMediaErrorCode;
}
type ChooseMediaFileType = 'image' | 'video';
class ChooseMediaTempFile extends UTSObject {
tempFilePath!: string;
fileType!: ChooseMediaFileType;
size!: number;
duration: number | null = null;
height: number | null = null;
width: number | null = null;
thumbTempFilePath: string | null = null;
}
export class ChooseMediaSuccess extends UTSObject {
tempFiles!: ChooseMediaTempFile[];
type!: 'image' | 'video' | 'mix';
}
type ChooseMediaFail = IChooseMediaError;
type ChooseMediaSuccessCallback = (callback: ChooseMediaSuccess) => void;
type ChooseMediaFailCallback = (callback: ChooseMediaFail) => void;
type ChooseMediaCompleteCallback = (callback: Object) => void;
type ChooseMediaPageOrientation = "auto" | "portrait" | "landscape";
export class ChooseMediaOptions extends UTSObject {
pageOrientation: ChooseMediaPageOrientation | null = null;
count: number | null = null;
mediaType: (string[]) | null = null;
sourceType: (string[]) | null = null;
maxDuration: number | null = null;
camera: 'front' | 'back' | null = null;
success: (ChooseMediaSuccessCallback) | null = null;
fail: (ChooseMediaFailCallback) | null = null;
complete: (ChooseMediaCompleteCallback) | null = null;
}
export type ChooseMedia = (options: ChooseMediaOptions) => void;
type _MediaOrientation = 'up' | 'down' | 'left' | 'right' | 'up-mirrored' | 'down-mirrored' | 'left-mirrored' | 'right-mirrored';
class _GetVideoInfoSuccess extends UTSObject {
orientation: _MediaOrientation | null = null;
type: string | null = null;
duration!: number;
size!: number;
height!: number;
width!: number;
fps: number | null = null;
bitrate: number | null = null;
}
interface _MediaFile {
fileType: 'video' | 'image';
tempFilePath: string;
size: number;
width?: number;
height?: number;
duration?: number;
thumbTempFilePath?: string;
}
interface __ChooseMediaOptions {
mimeType: photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE | photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE | photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
count?: number;
sourceType?: ('album' | 'camera')[];
isOriginalSupported?: boolean;
}
interface _chooseMediaSuccessCallbackResult {
tempFiles: _MediaFile[];
}
type CameraPosition = 'back' | 'front';
type UNI_MEDIA_TYPE = 'image' | 'video' | 'mix';
export type SetClipboardData = (options: SetClipboardDataOptions) => void;
export class SetClipboardDataSuccess extends UTSObject {
}
type SetClipboardDataSuccessCallback = (result: SetClipboardDataSuccess) => void;
type SetClipboardDataFail = UniError;
type SetClipboardDataFailCallback = (result: SetClipboardDataFail) => void;
type SetClipboardDataComplete = Object;
type SetClipboardDataCompleteCallback = (result: SetClipboardDataComplete) => void;
export class SetClipboardDataOptions extends UTSObject {
data!: string;
showToast: boolean | null = null;
success: SetClipboardDataSuccessCallback | null = null;
fail: SetClipboardDataFailCallback | null = null;
complete: SetClipboardDataCompleteCallback | null = null;
}
export type GetClipboardData = (options: GetClipboardDataOptions) => void;
export class GetClipboardDataSuccess extends UTSObject {
data!: string;
}
type GetClipboardDataSuccessCallback = (result: GetClipboardDataSuccess) => void;
type GetClipboardDataFail = UniError;
type GetClipboardDataFailCallback = (result: GetClipboardDataFail) => void;
type GetClipboardDataComplete = Object;
type GetClipboardDataCompleteCallback = (result: GetClipboardDataComplete) => void;
export class GetClipboardDataOptions extends UTSObject {
success: GetClipboardDataSuccessCallback | null = null;
fail: GetClipboardDataFailCallback | null = null;
complete: GetClipboardDataCompleteCallback | null = null;
}
class ClipboardCallbackOptions extends UTSObject {
data!: string;
result!: 'success' | 'fail';
}
type ClipboardCallback = (res: ClipboardCallbackOptions) => void;
type CreateInnerAudioContext = () => InnerAudioContext;
interface InnerAudioContext {
duration: number;
currentTime: number;
paused: boolean;
src: string;
startTime: number;
buffered: number;
autoplay: boolean;
loop: boolean;
obeyMuteSwitch: boolean;
volume: number;
playbackRate?: number;
pause(): void;
stop(): void;
play(): void;
seek(position: number): void;
destroy(): void;
onCanplay(callback: (result: Object) => void): void;
onPlay(callback: (result: Object) => void): void;
onPause(callback: (result: Object) => void): void;
onStop(callback: (result: Object) => void): void;
onEnded(callback: (result: Object) => void): void;
onTimeUpdate(callback: (result: Object) => void): void;
onError(callback: (result: ICreateInnerAudioContextFail) => void): void;
onWaiting(callback: (result: Object) => void): void;
onSeeking(callback: (result: Object) => void): void;
onSeeked(callback: (result: Object) => void): void;
offCanplay(callback: (result: Object) => void): void;
offPlay(callback: (result: Object) => void): void;
offPause(callback: (result: Object) => void): void;
offStop(callback: (result: Object) => void): void;
offEnded(callback: (result: Object) => void): void;
offTimeUpdate(callback: (result: Object) => void): void;
offError(callback: (result: ICreateInnerAudioContextFail) => void): void;
offWaiting(callback: (result: Object) => void): void;
offSeeking(callback: (result: Object) => void): void;
offSeeked(callback: (result: Object) => void): void;
}
type CreateInnerAudioContextErrorCode = 1107601 | 1107602 | 1107603 | 1107604 | 1107605 | 1107609;
interface ICreateInnerAudioContextFail extends IUniError {
errCode: CreateInnerAudioContextErrorCode;
}
type $OnCallback = Function;
type $On = (eventName: string, callback: $OnCallback) => number;
type $OnceCallback = Function;
type $Once = (eventName: string, callback: $OnceCallback) => number;
type $Off = (eventName: string, callback?: Object | null) => void;
type $Emit = (eventName: string, ...args: Array<Object | null>) => void;
interface IUniEventEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function | null) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
class ExitSuccess extends UTSObject {
errMsg!: string;
}
type ExitErrorCode = 12001 | 12002 | 12003;
interface IExitError extends IUniError {
errCode: ExitErrorCode;
}
type ExitFail = IExitError;
type ExitSuccessCallback = (res: ExitSuccess) => void;
type ExitFailCallback = (res: ExitFail) => void;
type ExitCompleteCallback = (res: Object) => void;
class ExitOptions extends UTSObject {
success: ExitSuccessCallback | null = null;
fail: ExitFailCallback | null = null;
complete: ExitCompleteCallback | null = null;
}
type Exit = (options?: ExitOptions | null) => void;
export class LegacySaveFileSuccess extends UTSObject {
savedFilePath!: string;
}
type LegacySaveFileSuccessCallback = (res: LegacySaveFileSuccess) => void;
export class LegacySaveFileFail extends UTSObject {
}
type LegacySaveFileFailCallback = (res: LegacySaveFileFail) => void;
type LegacySaveFileCompleteCallback = (res: Object) => void;
export class LegacySaveFileOptions extends UTSObject {
tempFilePath!: string;
success: LegacySaveFileSuccessCallback | null = null;
fail: LegacySaveFileFailCallback | null = null;
complete: LegacySaveFileCompleteCallback | null = null;
}
export class LegacyGetFileInfoSuccess extends UTSObject {
digest!: string;
size!: number;
}
type LegacyGetFileInfoSuccessCallback = (res: LegacyGetFileInfoSuccess) => void;
export class LegacyGetFileInfoFail extends UTSObject {
}
type LegacyGetFileInfoFailCallback = (res: LegacyGetFileInfoFail) => void;
type LegacyGetFileInfoCompleteCallback = (res: Object) => void;
export class LegacyGetFileInfoOptions extends UTSObject {
filePath!: string;
digestAlgorithm: string | null = null;
success: LegacyGetFileInfoSuccessCallback | null = null;
fail: LegacyGetFileInfoFailCallback | null = null;
complete: LegacyGetFileInfoCompleteCallback | null = null;
}
export class LegacyGetSavedFileInfoSuccess extends UTSObject {
size!: number;
createTime!: number;
}
type LegacyGetSavedFileInfoSuccessCallback = (res: LegacyGetSavedFileInfoSuccess) => void;
export class LegacyGetSavedFileInfoFail extends UTSObject {
}
type LegacyGetSavedFileInfoFailCallback = (res: LegacyGetSavedFileInfoFail) => void;
type LegacyGetSavedFileInfoCompleteCallback = (res: Object) => void;
export class LegacyGetSavedFileInfoOptions extends UTSObject {
filePath!: string;
success: LegacyGetSavedFileInfoSuccessCallback | null = null;
fail: LegacyGetSavedFileInfoFailCallback | null = null;
complete: LegacyGetSavedFileInfoCompleteCallback | null = null;
}
export class LegacyRemoveSavedFileSuccess extends UTSObject {
}
type LegacyRemoveSavedFileSuccessCallback = (res: LegacyRemoveSavedFileSuccess) => void;
export class LegacyRemoveSavedFileFail extends UTSObject {
}
type LegacyRemoveSavedFileFailCallback = (res: LegacyRemoveSavedFileFail) => void;
type LegacyRemoveSavedFileCompleteCallback = (res: Object) => void;
export class LegacyRemoveSavedFileOptions extends UTSObject {
filePath!: string;
success: LegacyRemoveSavedFileSuccessCallback | null = null;
fail: LegacyRemoveSavedFileFailCallback | null = null;
complete: LegacyRemoveSavedFileCompleteCallback | null = null;
}
export class LegacySavedFileListItem extends UTSObject {
filePath!: string;
size!: number;
createTime!: number;
}
export class LegacyGetSavedFileListSuccess extends UTSObject {
fileList!: LegacySavedFileListItem[];
}
type LegacyGetSavedFileListSuccessCallback = (res: LegacyGetSavedFileListSuccess) => void;
export class LegacyGetSavedFileListFail extends UTSObject {
}
type LegacyGetSavedFileListFailCallback = (res: LegacyGetSavedFileListFail) => void;
type LegacyGetSavedFileListCompleteCallback = (res: Object) => void;
export class LegacyGetSavedFileListOptions extends UTSObject {
success: LegacyGetSavedFileListSuccessCallback | null = null;
fail: LegacyGetSavedFileListFailCallback | null = null;
complete: LegacyGetSavedFileListCompleteCallback | null = null;
}
export type SaveFile = (options?: LegacySaveFileOptions | null) => void;
export type GetFileInfo = (options?: LegacyGetFileInfoOptions | null) => void;
export type GetSavedFileInfo = (options?: LegacyGetSavedFileInfoOptions | null) => void;
export type RemoveSavedFile = (options?: LegacyRemoveSavedFileOptions | null) => void;
export type GetSavedFileList = (options?: LegacyGetSavedFileListOptions | null) => void;
class ReadFileSuccessResult extends UTSObject {
data!: Object;
}
class OpenFileSuccessResult extends UTSObject {
fd!: string;
errMsg: string | null = null;
}
class FileManagerSuccessResult extends UTSObject {
errMsg!: string;
}
type FileManagerSuccessCallback = (res: FileManagerSuccessResult) => void;
type FileManagerFailCallback = (res: FileSystemManagerFail) => void;
type FileManagerCompleteCallback = (res: Object) => void;
type ReadFileSuccessCallback = (res: ReadFileSuccessResult) => void;
class ReadFileOptions extends UTSObject {
encoding: "base64" | "utf-8" | "ascii" | null = null;
filePath!: string.URIString;
success: ReadFileSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class WriteFileOptions extends UTSObject {
filePath!: string.URIString;
encoding: "ascii" | "base64" | "utf-8" | null = null;
data!: Object;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class AppendFileOptions extends UTSObject {
filePath!: string.URIString;
encoding: "ascii" | "base64" | "utf-8" | null = null;
data!: Object;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
type OpenFileSuccessCallback = (res: OpenFileSuccessResult) => void;
class OpenFileOptions extends UTSObject {
filePath!: string.URIString;
flag!: "a" | "ax" | "a+" | "ax+" | "r" | "r+" | "w" | "wx" | "w+" | "wx" | "wx+";
success: OpenFileSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class OpenFileSyncOptions extends UTSObject {
filePath!: string.URIString;
flag!: "a" | "ax" | "a+" | "ax+" | "r" | "r+" | "w" | "wx" | "w+" | "wx" | "wx+";
}
type UnLinkSuccessCallback = (res: FileManagerSuccessResult) => void;
class UnLinkOptions extends UTSObject {
filePath!: string.URIString;
success: UnLinkSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
type MkDirSuccessCallback = (res: FileManagerSuccessResult) => void;
class MkDirOptions extends UTSObject {
dirPath!: string.URIString;
recursive!: boolean;
success: MkDirSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class RmDirOptions extends UTSObject {
dirPath!: string.URIString;
recursive!: boolean;
success: MkDirSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class ReadDirSuccessResult extends UTSObject {
files!: string[];
errMsg: string | null = null;
}
type ReadDirSuccessCallback = (res: ReadDirSuccessResult) => void;
class ReadDirOptions extends UTSObject {
dirPath!: string.URIString;
success: ReadDirSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class AccessOptions extends UTSObject {
path!: string.URIString;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class RenameOptions extends UTSObject {
oldPath!: string.URIString;
newPath!: string.URIString;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class CopyFileOptions extends UTSObject {
srcPath!: string.URIString;
destPath!: string.URIString;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class SaveFileOptions extends UTSObject {
tempFilePath!: string.URIString;
filePath: string.URIString | null = null;
success: SaveFileSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
type SaveFileSuccessCallback = (res: SaveFileSuccessResult) => void;
class SaveFileSuccessResult extends UTSObject {
savedFilePath!: string;
}
class GetFileInfoSuccessResult extends UTSObject {
digest!: string;
size!: number;
errMsg!: string;
}
type GetFileInfoSuccessCallback = (res: GetFileInfoSuccessResult) => void;
class GetFileInfoOptions extends UTSObject {
filePath!: string.URIString;
digestAlgorithm: "md5" | "sha1" | null = null;
success: GetFileInfoSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
interface Stats {
mode: number;
size: number;
lastAccessedTime: number;
lastModifiedTime: number;
mIsFile: boolean;
isDirectory(): boolean;
isFile(): boolean;
}
class FileStats extends UTSObject {
path!: string;
stats!: Stats;
}
class StatSuccessResult extends UTSObject {
errMsg!: string;
stats!: FileStats[];
}
type StatSuccessCallback = (res: StatSuccessResult) => void;
class StatOptions extends UTSObject {
path!: string.URIString;
recursive!: boolean;
success: StatSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class UnzipFileOptions extends UTSObject {
zipFilePath!: string;
targetPath!: string;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class GetSavedFileListResult extends UTSObject {
fileList!: string[];
}
type GetSavedFileListCallback = (res: GetSavedFileListResult) => void;
class GetSavedFileListOptions extends UTSObject {
success: GetSavedFileListCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class TruncateFileOptions extends UTSObject {
filePath!: string.URIString;
length!: number;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class ReadCompressedFileResult extends UTSObject {
data!: string;
}
type ReadCompressedFileCallback = (res: ReadCompressedFileResult) => void;
class ReadCompressedFileOptions extends UTSObject {
filePath!: string.URIString;
compressionAlgorithm!: "br";
success: ReadCompressedFileCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class RemoveSavedFileOptions extends UTSObject {
filePath!: string.URIString;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class WriteResult extends UTSObject {
bytesWritten!: number;
errMsg!: string;
}
type WriteCallback = (res: WriteResult) => void;
class WriteOptions extends UTSObject {
fd!: string;
data!: Object;
offset: number | null = null;
length: number | null = null;
position: number | null = null;
encoding: "ascii" | "base64" | "utf-8" | null = null;
success: WriteCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class WriteSyncOptions extends UTSObject {
fd!: string;
data!: Object;
encoding: "ascii" | "base64" | "utf-8" | null = null;
length: number | null = null;
offset: number | null = null;
position: number | null = null;
}
class CloseOptions extends UTSObject {
fd!: string;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class CloseSyncOptions extends UTSObject {
fd!: string;
}
class FStatSuccessResult extends UTSObject {
stats!: Stats;
}
type FStatSuccessCallback = (res: FStatSuccessResult) => void;
class FStatOptions extends UTSObject {
fd!: string;
success: FStatSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class FStatSyncOptions extends UTSObject {
fd!: string;
}
class FTruncateFileOptions extends UTSObject {
fd!: string;
length!: number;
success: FileManagerSuccessCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class FTruncateFileSyncOptions extends UTSObject {
fd!: string;
length!: number;
}
class EntryItem extends UTSObject {
path!: string;
encoding: "ascii" | "base64" | "utf-8" | null = null;
}
class EntriesResult extends UTSObject {
entries!: Map<string, ZipFileItem>;
result!: Map<string, ZipFileItem>;
errMsg: string | null = null;
}
class ZipFileItem extends UTSObject {
data: Object | null = null;
errMsg!: string;
}
type ReadZipEntryCallback = (res: EntriesResult) => void;
class ReadZipEntryOptions extends UTSObject {
filePath!: string.URIString;
encoding: "ascii" | "base64" | "utf-8" | null = null;
entries: EntryItem[] | null = null;
success: ReadZipEntryCallback | null = null;
fail: FileManagerFailCallback | null = null;
complete: FileManagerCompleteCallback | null = null;
}
class ReadSuccessCallbackResult extends UTSObject {
arrayBuffer!: ArrayBuffer;
bytesRead!: number;
errMsg!: string;
}
type ReadSuccessCallback = (result: ReadSuccessCallbackResult) => void;
class ReadOption extends UTSObject {
arrayBuffer!: ArrayBuffer;
fd!: string;
length: number | null = null;
offset: number | null = null;
position: number | null = null;
complete: FileManagerCompleteCallback | null = null;
fail: FileManagerFailCallback | null = null;
success: ReadSuccessCallback | null = null;
}
class ReadSyncOption extends UTSObject {
arrayBuffer!: ArrayBuffer;
fd!: string;
length: number | null = null;
offset: number | null = null;
position: number | null = null;
}
class ReadResult extends UTSObject {
arrayBuffer!: ArrayBuffer;
bytesRead!: number;
}
interface FileSystemManager {
readFile(options: ReadFileOptions): void;
readFileSync(filePath: string, encoding?: string): Object;
writeFile(options: WriteFileOptions): void;
read(option: ReadOption): void;
readSync(option: ReadSyncOption): ReadResult;
writeFileSync(filePath: string, data: Object, encoding?: string): void;
unlink(options: UnLinkOptions): void;
unlinkSync(filePath: string): void;
mkdir(options: MkDirOptions): void;
mkdirSync(dirPath: string, recursive: boolean): void;
rmdir(options: RmDirOptions): void;
rmdirSync(dirPath: string, recursive: boolean): void;
readdir(options: ReadDirOptions): void;
readdirSync(dirPath: string): string[] | null;
access(options: AccessOptions): void;
accessSync(path: string): void;
rename(options: RenameOptions): void;
renameSync(oldPath: string, newPath: string): void;
copyFile(options: CopyFileOptions): void;
copyFileSync(srcPath: string, destPath: string): void;
getFileInfo(options: GetFileInfoOptions): void;
stat(options: StatOptions): void;
statSync(path: string, recursive: boolean): FileStats[];
appendFile(options: AppendFileOptions): void;
appendFileSync(filePath: string, data: Object, encoding?: string): void;
saveFile(options: SaveFileOptions): void;
saveFileSync(tempFilePath: string, filePath: string | null): string;
removeSavedFile(options: RemoveSavedFileOptions): void;
unzip(options: UnzipFileOptions): void;
getSavedFileList(options: GetSavedFileListOptions): void;
truncate(options: TruncateFileOptions): void;
truncateSync(filePath: string, length?: number): void;
readCompressedFile(options: ReadCompressedFileOptions): void;
readCompressedFileSync(filePath: string, compressionAlgorithm: string): string;
open(options: OpenFileOptions): void;
openSync(options: OpenFileSyncOptions): string;
write(options: WriteOptions): void;
writeSync(options: WriteSyncOptions): WriteResult;
close(options: CloseOptions): void;
closeSync(options: CloseSyncOptions): void;
fstat(options: FStatOptions): void;
fstatSync(options: FStatSyncOptions): Stats;
ftruncate(options: FTruncateFileOptions): void;
ftruncateSync(options: FTruncateFileSyncOptions): void;
readZipEntry(options: ReadZipEntryOptions): void;
}
type GetFileSystemManager = () => FileSystemManager;
type FileSystemManagerErrorCode = 1200002 | 1300002 | 1300013 | 1300021 | 1300022 | 1300066 | 1301003 | 1301005 | 1300201 | 1300202 | 1301111 | 1302003 | 1300009 | 1300010 | 1300011 | 1300012 | 1300015 | 1300014 | 1300016 | 1300017 | 1300018 | 1300019 | 1300020 | 1300021;
type FileSystemManagerFail = IFileSystemManagerFail;
interface IFileSystemManagerFail extends IUniError {
errCode: FileSystemManagerErrorCode;
}
interface CallBack {
success?: Function | null;
fail?: Function | null;
complete?: Function | null;
}
type ModeReflect = Record<string, string>;
type BaseType = number | string | boolean | null | undefined;
type DataType = BaseType | Object | Function | ArrayBuffer | Array<BaseType>;
interface CustomValidReturn {
isValid: false;
err: IFileSystemManagerFail;
}
interface CustomValidReturnValid {
isValid: true;
}
interface ObtainUpperPathReturn {
index: number;
upperPath: string;
}
interface ObtainFileNameReturn {
index: number;
fileName: string;
}
interface CheckFd {
isValid: true;
fd: number;
}
interface CheckFdErr {
isValid: false;
fd: number;
err: IFileSystemManagerFail;
}
interface CheckEncodingReturn {
isValid: boolean;
errMsg: string;
}
interface FileSystemManagerApiError extends ApiError {
errMsg: string;
}
type _FLAG = "a" | "ax" | "a+" | "ax+" | "r" | "r+" | "w" | "wx" | "w+" | "wx+";
type GetAppAuthorizeSetting = () => GetAppAuthorizeSettingResult;
class GetAppAuthorizeSettingResult extends UTSObject {
albumAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
bluetoothAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
cameraAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
locationAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
locationAccuracy: 'reduced' | 'full' | 'unsupported' | null = null;
locationReducedAccuracy: boolean | null = null;
microphoneAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
notificationAuthorized!: 'authorized' | 'denied' | 'not determined' | 'config error';
notificationAlertAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error' | null = null;
notificationBadgeAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error' | null = null;
notificationSoundAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error' | null = null;
phoneCalendarAuthorized: 'authorized' | 'denied' | 'not determined' | null = null;
}
class GetAppBaseInfoOptions extends UTSObject {
filter!: Array<string>;
}
export class GetAppBaseInfoResult extends UTSObject {
appId: string | null = null;
appName: string | null = null;
appVersion: string | null = null;
appVersionCode: string | null = null;
appLanguage: string | null = null;
language: string | null = null;
version: string | null = null;
appWgtVersion: string | null = null;
hostLanguage: string | null = null;
hostVersion: string | null = null;
hostName: string | null = null;
hostPackageName: string | null = null;
hostSDKVersion: string | null = null;
hostTheme: string | null = null;
isUniAppX: boolean | null = null;
uniCompileVersion: string | null = null;
uniCompilerVersion: string | null = null;
uniPlatform: 'app' | 'web' | 'mp-weixin' | 'mp-alipay' | 'mp-baidu' | 'mp-toutiao' | 'mp-lark' | 'mp-qq' | 'mp-kuaishou' | 'mp-jd' | 'mp-360' | 'quickapp-webview' | 'quickapp-webview-union' | 'quickapp-webview-huawei' | null = null;
uniRuntimeVersion: string | null = null;
uniCompileVersionCode: number | null = null;
uniCompilerVersionCode: number | null = null;
uniRuntimeVersionCode: number | null = null;
packageName: string | null = null;
bundleId: string | null = null;
signature: string | null = null;
appTheme: 'light' | 'dark' | 'auto' | null = null;
channel: string | null = null;
}
export type GetAppBaseInfo = (options?: GetAppBaseInfoOptions | null) => GetAppBaseInfoResult;
interface IAppBaseInfoAppVersion {
name: string;
code: string;
}
type GetBackgroundAudioManager = () => BackgroundAudioManager;
interface BackgroundAudioManager {
duration: number;
currentTime: number;
paused: boolean;
src: string;
startTime: number;
buffered: number;
title: string;
epname: string;
singer: string;
coverImgUrl: string;
webUrl: string;
protocol: string;
playbackRate?: number;
play(): void;
pause(): void;
seek(position: number): void;
stop(): void;
onCanplay(callback: (result: Object) => void): void;
onPlay(callback: (result: Object) => void): void;
onPause(callback: (result: Object) => void): void;
onStop(callback: (result: Object) => void): void;
onEnded(callback: (result: Object) => void): void;
onSeeking(callback: (result: Object) => void): void;
onSeeked(callback: (result: Object) => void): void;
onTimeUpdate(callback: (result: Object) => void): void;
onPrev(callback: (result: Object) => void): void;
onNext(callback: (result: Object) => void): void;
onError(callback: (result: ICreateBackgroundAudioFail) => void): void;
onWaiting(callback: (result: Object) => void): void;
}
type CreateBackgroundAudioErrorCode = 1107601 | 1107602 | 1107603 | 1107604 | 1107605 | 1107609;
interface ICreateBackgroundAudioFail extends IUniError {
errCode: CreateBackgroundAudioErrorCode;
}
interface TempAbilityInfo {
bundleName: string;
name: string;
}
class GetDeviceInfoOptions extends UTSObject {
filter!: Array<string>;
}
export class GetDeviceInfoResult extends UTSObject {
brand: string | null = null;
deviceBrand: string | null = null;
deviceId: string | null = null;
model: string | null = null;
deviceModel: string | null = null;
deviceType: 'phone' | 'pad' | 'tv' | 'watch' | 'pc' | 'undefined' | 'car' | 'vr' | 'appliance' | null = null;
deviceOrientation: string | null = null;
devicePixelRatio: number | null = null;
system: string | null = null;
platform: 'ios' | 'android' | 'harmonyos' | 'mac' | 'windows' | 'linux' | null = null;
isRoot: boolean | null = null;
isSimulator: boolean | null = null;
isUSBDebugging: boolean | null = null;
osName: 'ios' | 'android' | 'harmonyos' | 'macos' | 'windows' | 'linux' | null = null;
osVersion: string | null = null;
osLanguage: string | null = null;
osTheme: 'light' | 'dark' | null = null;
osAndroidAPILevel: number | null = null;
romName: string | null = null;
romVersion: string | null = null;
}
export type GetDeviceInfo = (options?: GetDeviceInfoOptions | null) => GetDeviceInfoResult;
type GetNetworkType = (options: GetNetworkTypeOptions) => void;
class GetNetworkTypeSuccess extends UTSObject {
networkType!: string;
}
type GetNetworkTypeSuccessCallback = (result: GetNetworkTypeSuccess) => void;
type GetNetworkTypeFail = UniError;
type GetNetworkTypeFailCallback = (result: GetNetworkTypeFail) => void;
type GetNetworkTypeComplete = Object;
type GetNetworkTypeCompleteCallback = (result: GetNetworkTypeComplete) => void;
class GetNetworkTypeOptions extends UTSObject {
success: GetNetworkTypeSuccessCallback | null = null;
fail: GetNetworkTypeFailCallback | null = null;
complete: GetNetworkTypeCompleteCallback | null = null;
}
class OnNetworkStatusChangeCallbackResult extends UTSObject {
isConnected!: boolean;
networkType!: string;
}
type OnNetworkStatusChangeCallback = (result: OnNetworkStatusChangeCallbackResult) => void;
type OnNetworkStatusChange = (callback: OnNetworkStatusChangeCallback) => void;
type OffNetworkStatusChange = (callback: (result: Object) => void) => void;
interface IUniGetNetworkTypeEventEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
export class GetProviderSuccess extends UTSObject {
service!: 'payment' | 'oauth';
provider!: string[];
providers!: UniProvider[];
}
export class GetProviderSyncSuccess extends UTSObject {
service!: 'payment' | 'location' | 'oauth';
providerIds!: string[];
providerObjects!: UniProvider[];
}
export type GetProviderSync = (options: GetProviderSyncOptions) => GetProviderSyncSuccess;
export class GetProviderSyncOptions extends UTSObject {
service!: 'payment' | 'location' | 'oauth';
}
type GetProviderSuccessCallback = (result: GetProviderSuccess) => void;
type GetProviderFail = IGetProviderFail;
type GetProviderFailCallback = (result: GetProviderFail) => void;
type GetProviderComplete = Object;
type GetProviderCompleteCallback = (result: GetProviderComplete) => void;
export class GetProviderOptions extends UTSObject {
service!: 'payment' | 'oauth';
success: GetProviderSuccessCallback | null = null;
fail: GetProviderFailCallback | null = null;
complete: GetProviderCompleteCallback | null = null;
}
export type GetProvider = (options: GetProviderOptions) => void;
type ProviderErrorCode = 110600;
interface IGetProviderFail extends IUniError {
errCode: ProviderErrorCode;
}
type GetRecorderManager = () => RecorderManager;
class RecorderManagerStartOptions extends UTSObject {
duration: number | null = null;
sampleRate: number | null = null;
numberOfChannels: number | null = null;
encodeBitRate: number | null = null;
format: 'aac' | 'mp3' | 'PCM' | 'wav' | null = null;
frameSize: number | null = null;
}
interface RecorderManagerOnStopResult {
tempFilePath: string;
}
interface RecorderManager {
start(options: RecorderManagerStartOptions): void;
pause(): void;
resume(): void;
stop(): void;
onStart(options: (result: Object) => void): void;
onPause(options: (result: Object) => void): void;
onStop(options: (result: RecorderManagerOnStopResult) => void): void;
onFrameRecorded(options: (result: Object) => void): void;
onError(options: (result: Object) => void): void;
onResume?: (options: (result: Object) => void) => void;
onInterruptionBegin?: (options: (result: Object) => void) => void;
onInterruptionEnd?: (options: (result: Object) => void) => void;
}
type RecorderState = 'pause' | 'resume' | 'start' | 'stop' | 'error' | 'frameRecorded' | 'interruptionBegin' | 'interruptionEnd';
interface Callbacks {
pause?: Function;
resume?: Function;
start?: Function;
stop?: Function;
error?: Function;
frameRecorded?: Function;
interruptionBegin?: Function;
interruptionEnd?: Function;
}
interface StateChangeRes extends RecorderManagerOnStopResult {
errMsg?: string;
frameBuffer?: ArrayBuffer;
isLastFrame?: boolean;
}
export type GetSystemInfo = (options: GetSystemInfoOptions) => void;
export type GetSystemInfoSync = () => GetSystemInfoResult;
export type GetWindowInfo = () => GetWindowInfoResult;
export class SafeArea extends UTSObject {
left!: number;
right!: number;
top!: number;
bottom!: number;
width!: number;
height!: number;
}
export class SafeAreaInsets extends UTSObject {
left!: number;
right!: number;
top!: number;
bottom!: number;
}
export class GetSystemInfoResult extends UTSObject {
SDKVersion!: string;
appId!: string;
appLanguage!: string;
appName!: string;
appVersion!: string;
appVersionCode!: string;
appWgtVersion: string | null = null;
brand!: string;
browserName!: string;
browserVersion!: string;
deviceId!: string;
deviceBrand!: string;
deviceModel!: string;
deviceType!: 'phone' | 'pad' | 'tv' | 'watch' | 'pc' | 'undefined' | 'car' | 'vr' | 'appliance';
devicePixelRatio!: number;
deviceOrientation!: 'portrait' | 'landscape';
language!: string;
model: string | null = null;
osName!: 'ios' | 'android' | 'harmonyos' | 'macos' | 'windows' | 'linux';
osVersion!: string;
osLanguage!: string;
osTheme: 'light' | 'dark' | null = null;
pixelRatio!: number;
platform!: 'ios' | 'android' | 'harmonyos' | 'mac' | 'windows' | 'linux';
screenWidth!: number;
screenHeight!: number;
statusBarHeight!: number;
system!: string;
safeArea!: SafeArea;
safeAreaInsets!: SafeAreaInsets;
ua!: string;
uniCompileVersion!: string;
uniCompilerVersion!: string;
uniPlatform!: 'app' | 'web' | 'mp-weixin' | 'mp-alipay' | 'mp-baidu' | 'mp-toutiao' | 'mp-lark' | 'mp-qq' | 'mp-kuaishou' | 'mp-jd' | 'mp-360' | 'quickapp-webview' | 'quickapp-webview-union' | 'quickapp-webview-huawei';
uniRuntimeVersion!: string;
uniCompileVersionCode!: number;
uniCompilerVersionCode!: number;
uniRuntimeVersionCode!: number;
version!: string;
romName!: string;
romVersion!: string;
windowWidth!: number;
windowHeight!: number;
windowTop!: number;
windowBottom!: number;
osAndroidAPILevel: number | null = null;
appTheme: 'light' | 'dark' | 'auto' | null = null;
}
type GetSystemInfoSuccessCallback = (result: GetSystemInfoResult) => void;
type GetSystemInfoFail = UniError;
type GetSystemInfoFailCallback = (result: GetSystemInfoFail) => void;
type GetSystemInfoComplete = Object;
type GetSystemInfoCompleteCallback = (result: GetSystemInfoComplete) => void;
export class GetSystemInfoOptions extends UTSObject {
success: GetSystemInfoSuccessCallback | null = null;
fail: GetSystemInfoFailCallback | null = null;
complete: GetSystemInfoCompleteCallback | null = null;
}
export class GetWindowInfoResult extends UTSObject {
pixelRatio!: number;
screenWidth!: number;
screenHeight!: number;
windowWidth!: number;
windowHeight!: number;
statusBarHeight!: number;
windowTop!: number;
windowBottom!: number;
safeArea!: SafeArea;
safeAreaInsets!: SafeAreaInsets;
screenTop!: number;
}
interface ISystemInfoAppVersion {
name: string;
code: string;
}
class GetSystemSettingResult extends UTSObject {
bluetoothEnabled: boolean | null = null;
bluetoothError: string | null = null;
locationEnabled!: boolean;
wifiEnabled: boolean | null = null;
wifiError: string | null = null;
deviceOrientation!: 'portrait' | 'landscape';
}
type GetSystemSetting = () => GetSystemSettingResult;
export class HideKeyboardSuccess extends UTSObject {
}
export class HideKeyboardFail extends UTSObject {
}
type HideKeyboardSuccessCallback = (res: HideKeyboardSuccess) => void;
type HideKeyboardFailCallback = (res: HideKeyboardFail) => void;
type HideKeyboardCompleteCallback = (res: Object) => void;
export class HideKeyboardOptions extends UTSObject {
success: HideKeyboardSuccessCallback | null = null;
fail: HideKeyboardFailCallback | null = null;
complete: HideKeyboardCompleteCallback | null = null;
}
type HideKeyboard = (options?: HideKeyboardOptions | null) => void;
export type MakePhoneCall = (options: MakePhoneCallOptions) => void;
export class MakePhoneCallSuccess extends UTSObject {
}
type MakePhoneCallSuccessCallback = (result: MakePhoneCallSuccess) => void;
type MakePhoneCallFail = UniError;
type MakePhoneCallFailCallback = (result: MakePhoneCallFail) => void;
type MakePhoneCallComplete = Object;
type MakePhoneCallCompleteCallback = (result: MakePhoneCallComplete) => void;
export class MakePhoneCallOptions extends UTSObject {
phoneNumber!: string;
success: MakePhoneCallSuccessCallback | null = null;
fail: MakePhoneCallFailCallback | null = null;
complete: MakePhoneCallCompleteCallback | null = null;
}
type MediaOrientation = 'up' | 'down' | 'left' | 'right' | 'up-mirrored' | 'down-mirrored' | 'left-mirrored' | 'right-mirrored';
type MediaErrorCode = 1101001 | 1101002 | 1101003 | 1101004 | 1101005 | 1101006 | 1101007 | 1101008 | 1101009 | 1101010;
interface IMediaError extends IUniError {
errCode: MediaErrorCode;
}
class ChooseImageTempFile extends UTSObject {
path!: string;
size!: number;
name: string | null = null;
type: string | null = null;
}
export class ChooseImageSuccess extends UTSObject {
errSubject!: string;
errMsg!: string;
tempFilePaths!: Array<string>;
tempFiles!: ChooseImageTempFile[];
}
type ChooseImageFail = IMediaError;
type ChooseImageSuccessCallback = (callback: ChooseImageSuccess) => void;
type ChooseImageFailCallback = (callback: ChooseImageFail) => void;
type ChooseImageCompleteCallback = (callback: Object) => void;
class ChooseImageCropOptions extends UTSObject {
width!: number;
height!: number;
quality: (number) | null = null;
resize: (boolean) | null = null;
}
type ChooseImagePageOrientation = "auto" | "portrait" | "landscape";
type ChooseImageAlbumMode = "custom" | "system";
export class ChooseImageOptions extends UTSObject {
pageOrientation: ChooseImagePageOrientation | null = null;
albumMode: ChooseImageAlbumMode | null = null;
count: (number) | null = null;
sizeType: (string[]) | null = null;
sourceType: (string[]) | null = null;
extension: (string[]) | null = null;
crop: (ChooseImageCropOptions) | null = null;
success: (ChooseImageSuccessCallback) | null = null;
fail: (ChooseImageFailCallback) | null = null;
complete: (ChooseImageCompleteCallback) | null = null;
}
export type ChooseImage = (options: ChooseImageOptions) => void;
export class PreviewImageSuccess extends UTSObject {
errSubject!: string;
errMsg!: string;
}
type PreviewImageFail = IMediaError;
type PreviewImageSuccessCallback = (callback: PreviewImageSuccess) => void;
type PreviewImageFailCallback = (callback: PreviewImageFail) => void;
type PreviewImageCompleteCallback = ChooseImageCompleteCallback;
export class PreviewImageOptions extends UTSObject {
current: Object | null = null;
urls!: Array<string.ImageURIString>;
showmenu: boolean | null = null;
indicator: 'default' | 'number' | 'none' | null = null;
loop: boolean | null = null;
success: (PreviewImageSuccessCallback) | null = null;
fail: (PreviewImageFailCallback) | null = null;
complete: (PreviewImageCompleteCallback) | null = null;
}
export type PreviewImage = (options: PreviewImageOptions) => void;
export type ClosePreviewImage = (options: ClosePreviewImageOptions) => void;
export class ClosePreviewImageSuccess extends UTSObject {
errMsg!: string;
}
type ClosePreviewImageFail = IMediaError;
type ClosePreviewImageSuccessCallback = (callback: ClosePreviewImageSuccess) => void;
type ClosePreviewImageFailCallback = (callback: ClosePreviewImageFail) => void;
type ClosePreviewImageCompleteCallback = ChooseImageCompleteCallback;
export class ClosePreviewImageOptions extends UTSObject {
success: (ClosePreviewImageSuccessCallback) | null = null;
fail: (ClosePreviewImageFailCallback) | null = null;
complete: (ClosePreviewImageCompleteCallback) | null = null;
}
export type GetImageInfo = (options: GetImageInfoOptions) => void;
export class GetImageInfoSuccess extends UTSObject {
width!: number;
height!: number;
path!: string;
orientation: MediaOrientation | null = null;
type: string | null = null;
}
type GetImageInfoFail = IMediaError;
type GetImageInfoSuccessCallback = (callback: GetImageInfoSuccess) => void;
type GetImageInfoFailCallback = (callback: GetImageInfoFail) => void;
type GetImageInfoCompleteCallback = ChooseImageCompleteCallback;
export class GetImageInfoOptions extends UTSObject {
src!: string.ImageURIString;
success: (GetImageInfoSuccessCallback) | null = null;
fail: (GetImageInfoFailCallback) | null = null;
complete: (GetImageInfoCompleteCallback) | null = null;
}
export type SaveImageToPhotosAlbum = (options: SaveImageToPhotosAlbumOptions) => void;
export class SaveImageToPhotosAlbumSuccess extends UTSObject {
path!: string;
}
type SaveImageToPhotosAlbumFail = IMediaError;
type SaveImageToPhotosAlbumSuccessCallback = (callback: SaveImageToPhotosAlbumSuccess) => void;
type SaveImageToPhotosAlbumFailCallback = (callback: SaveImageToPhotosAlbumFail) => void;
type SaveImageToPhotosAlbumCompleteCallback = ChooseImageCompleteCallback;
export class SaveImageToPhotosAlbumOptions extends UTSObject {
filePath!: string.ImageURIString;
success: (SaveImageToPhotosAlbumSuccessCallback) | null = null;
fail: (SaveImageToPhotosAlbumFailCallback) | null = null;
complete: (SaveImageToPhotosAlbumCompleteCallback) | null = null;
}
type CompressImage = (options: CompressImageOptions) => void;
class CompressImageSuccess extends UTSObject {
tempFilePath!: string;
}
type CompressImageFail = IMediaError;
type CompressImageSuccessCallback = (callback: CompressImageSuccess) => void;
type CompressImageFailCallback = (callback: CompressImageFail) => void;
type CompressImageCompleteCallback = ChooseImageCompleteCallback;
class CompressImageOptions extends UTSObject {
src!: string.ImageURIString;
quality: number | null = null;
rotate: number | null = null;
width: string | null = null;
height: string | null = null;
compressedHeight: number | null = null;
compressedWidth: number | null = null;
success: (CompressImageSuccessCallback) | null = null;
fail: (CompressImageFailCallback) | null = null;
complete: (CompressImageCompleteCallback) | null = null;
}
export class ChooseVideoSuccess extends UTSObject {
tempFilePath!: string;
duration!: number;
size!: number;
height!: number;
width!: number;
}
type ChooseVideoFail = IMediaError;
type ChooseVideoSuccessCallback = (callback: ChooseVideoSuccess) => void;
type ChooseVideoFailCallback = (callback: ChooseVideoFail) => void;
type ChooseVideoCompleteCallback = ChooseImageCompleteCallback;
type ChooseVideoPageOrientation = ChooseImagePageOrientation;
type ChooseVideoAlbumMode = ChooseImageAlbumMode;
export class ChooseVideoOptions extends UTSObject {
pageOrientation: ChooseVideoPageOrientation | null = null;
albumMode: ChooseVideoAlbumMode | null = null;
sourceType: (string[]) | null = null;
compressed: boolean | null = true;
maxDuration: number | null = null;
camera: 'front' | 'back' | null = null;
extension: (string[]) | null = null;
success: (ChooseVideoSuccessCallback) | null = null;
fail: (ChooseVideoFailCallback) | null = null;
complete: (ChooseVideoCompleteCallback) | null = null;
}
export type ChooseVideo = (options: ChooseVideoOptions) => void;
export class GetVideoInfoSuccess extends UTSObject {
orientation: MediaOrientation | null = null;
type: string | null = null;
duration!: number;
size!: number;
height!: number;
width!: number;
fps: number | null = null;
bitrate: number | null = null;
}
type GetVideoInfoFail = IMediaError;
type GetVideoInfoSuccessCallback = (callback: GetVideoInfoSuccess) => void;
type GetVideoInfoFailCallback = (callback: GetVideoInfoFail) => void;
type GetVideoInfoCompleteCallback = ChooseImageCompleteCallback;
export class GetVideoInfoOptions extends UTSObject {
src!: string.VideoURIString;
success: (GetVideoInfoSuccessCallback) | null = null;
fail: (GetVideoInfoFailCallback) | null = null;
complete: (GetVideoInfoCompleteCallback) | null = null;
}
export type GetVideoInfo = (options: GetVideoInfoOptions) => void;
export class SaveVideoToPhotosAlbumSuccess extends UTSObject {
}
type SaveVideoToPhotosAlbumFail = IMediaError;
type SaveVideoToPhotosAlbumSuccessCallback = (callback: SaveVideoToPhotosAlbumSuccess) => void;
type SaveVideoToPhotosAlbumFailCallback = (callback: SaveVideoToPhotosAlbumFail) => void;
type SaveVideoToPhotosAlbumCompleteCallback = ChooseImageCompleteCallback;
export class SaveVideoToPhotosAlbumOptions extends UTSObject {
filePath!: string.VideoURIString;
success: (SaveVideoToPhotosAlbumSuccessCallback) | null = null;
fail: (SaveVideoToPhotosAlbumFailCallback) | null = null;
complete: (SaveVideoToPhotosAlbumCompleteCallback) | null = null;
}
export type SaveVideoToPhotosAlbum = (options: SaveVideoToPhotosAlbumOptions) => void;
export class CompressVideoSuccess extends UTSObject {
tempFilePath!: string;
size!: number;
}
type CompressVideoFail = IMediaError;
type CompressVideoSuccessCallback = (callback: CompressVideoSuccess) => void;
type CompressVideoFailCallback = (callback: CompressVideoFail) => void;
type CompressVideoCompleteCallback = ChooseImageCompleteCallback;
export class CompressVideoOptions extends UTSObject {
src!: string.VideoURIString;
quality: string | null = null;
bitrate: number | null = null;
fps: number | null = null;
resolution: number | null = null;
success: (CompressVideoSuccessCallback) | null = null;
fail: (CompressVideoFailCallback) | null = null;
complete: (CompressVideoCompleteCallback) | null = null;
}
export type CompressVideo = (options: CompressVideoOptions) => void;
export type ChooseFile = (options: ChooseFileOptions) => void;
export class ChooseFileSuccess extends UTSObject {
tempFilePaths!: string[];
tempFiles!: ChooseFileTempFile[];
}
class ChooseFileTempFile extends UTSObject {
name!: string;
path!: string;
size!: number;
type!: 'video' | 'image' | 'audio' | 'file';
}
type ChooseFileSuccessCallback = (result: ChooseFileSuccess) => void;
type ChooseFileFail = IMediaError;
type ChooseFileFailCallback = (result: ChooseFileFail) => void;
type ChooseFileComplete = Object;
type ChooseFileCompleteCallback = (result: ChooseFileComplete) => void;
export class ChooseFileOptions extends UTSObject {
count: number | null = null;
type: 'image' | 'video' | 'all' | 'audio' | null = null;
extension: (string[]) | null = null;
sizeType: Object | null = null;
sourceType: (string[]) | null = null;
success: ChooseFileSuccessCallback | null = null;
fail: ChooseFileFailCallback | null = null;
complete: ChooseFileCompleteCallback | null = null;
}
interface _CompressImageSuccess {
size: number;
tempFilePath: string;
}
interface MediaFile {
fileType: 'video' | 'image';
tempFilePath: string;
size: number;
width?: number;
height?: number;
duration?: number;
thumbTempFilePath?: string;
}
interface _ChooseMediaOptions {
mimeType: photoAccessHelper2.PhotoViewMIMETypes.VIDEO_TYPE | photoAccessHelper2.PhotoViewMIMETypes.IMAGE_TYPE | photoAccessHelper2.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
count?: number;
sourceType?: ('album' | 'camera')[];
isOriginalSupported?: boolean;
}
interface chooseMediaSuccessCallbackResult {
tempFiles: MediaFile[];
}
type CameraPosition1 = 'back' | 'front';
interface TempFiles {
tempFilePath: string;
size: number;
}
interface TakePhotoRes {
tempFiles: TempFiles[];
}
interface TakeVideoOptions {
cameraType?: CameraPosition1;
videoDuration?: number;
}
interface TakeVideoRes {
path: string;
duration: number;
size: number;
height: number;
width: number;
orientation: MediaOrientation;
type: string;
}
interface IGetImageInfoDownloadOptions {
url: string;
success: (res: IGetImageInfoDownloadSuccess) => void;
fail: (err: IGetImageInfoDownloadFail) => void;
}
interface IGetImageInfoDownloadSuccess {
tempFilePath: string;
}
interface IGetImageInfoDownloadFail {
errMsg: string;
}
interface IPreviewImageOptions {
urls: string[];
current: string;
showmenu: boolean;
}
interface ISaveMediaError {
code: number;
message: string;
}
export type Request<T = Object> = (param: RequestOptions<T>) => RequestTask;
export class RequestOptions<T = Object> extends UTSObject {
url!: string;
data: Object | null = null;
header: UTSJSONObject | null = null;
method: RequestMethod | null = null;
timeout: number | null = null;
dataType: string | null = null;
responseType: string | null = null;
sslVerify: boolean | null = null;
withCredentials: boolean | null = null;
firstIpv4: boolean | null = null;
success: RequestSuccessCallback<T> | null = null;
fail: RequestFailCallback | null = null;
complete: RequestCompleteCallback | null = null;
}
export class RequestSuccess<T = Object> extends UTSObject {
data: T | null = null;
statusCode!: number;
header!: Object;
cookies!: Array<string>;
}
type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
type RequestErrorCode = 5 | 1000 | 100001 | 100002 | 600003 | 600008 | 600009 | 602001;
export interface RequestFail extends IUniError {
errCode: RequestErrorCode;
}
type RequestSuccessCallback<T> = (option: RequestSuccess<T>) => void;
type RequestFailCallback = (option: RequestFail) => void;
type RequestCompleteCallback = (option: Object) => void;
export interface RequestTask {
abort(): void;
}
export type UploadFile = (options: UploadFileOptions) => UploadTask;
class UploadFileOptionFiles extends UTSObject {
name: string | null = null;
uri!: string;
file: Object | null = null;
}
export class UploadFileSuccess extends UTSObject {
data!: string;
statusCode!: number;
}
type UploadFileSuccessCallback = (result: UploadFileSuccess) => void;
interface UploadFileFail extends IUniError {
errCode: RequestErrorCode;
}
type UploadFileFailCallback = (result: UploadFileFail) => void;
type UploadFileCompleteCallback = (result: Object) => void;
export class UploadFileOptions extends UTSObject {
url!: string;
filePath: string | null = null;
name: string | null = null;
files: (UploadFileOptionFiles[]) | null = null;
header: UTSJSONObject | null = null;
formData: UTSJSONObject | null = null;
timeout: number | null = null;
success: UploadFileSuccessCallback | null = null;
fail: UploadFileFailCallback | null = null;
complete: UploadFileCompleteCallback | null = null;
}
export class OnProgressUpdateResult extends UTSObject {
progress!: number;
totalBytesSent!: number;
totalBytesExpectedToSend!: number;
}
type UploadFileProgressUpdateCallback = (result: OnProgressUpdateResult) => void;
export interface UploadTask {
abort(): void;
onProgressUpdate(callback: UploadFileProgressUpdateCallback): void;
}
export type DownloadFile = (options: DownloadFileOptions) => DownloadTask;
export class DownloadFileSuccess extends UTSObject {
tempFilePath!: string;
statusCode!: number;
}
type DownloadFileSuccessCallback = (result: DownloadFileSuccess) => void;
interface DownloadFileFail extends IUniError {
errCode: RequestErrorCode;
}
type DownloadFileFailCallback = (result: DownloadFileFail) => void;
type DownloadFileComplete = Object;
type DownloadFileCompleteCallback = (result: DownloadFileComplete) => void;
export class DownloadFileOptions extends UTSObject {
url!: string;
header: UTSJSONObject | null = null;
filePath: string | null = null;
timeout: number | null = null;
success: DownloadFileSuccessCallback | null = null;
fail: DownloadFileFailCallback | null = null;
complete: DownloadFileCompleteCallback | null = null;
}
export class OnProgressDownloadResult extends UTSObject {
progress!: number;
totalBytesWritten!: number;
totalBytesExpectedToWrite!: number;
}
type DownloadFileProgressUpdateCallback = (result: OnProgressDownloadResult) => void;
export interface DownloadTask {
abort(): void;
onProgressUpdate(callback: DownloadFileProgressUpdateCallback): void;
}
export type ConfigMTLS = (options: ConfigMTLSOptions) => void;
class Certificate extends UTSObject {
host!: string;
client: string | null = null;
clientPassword: string | null = null;
keyPath: string | null = null;
server: (string[]) | null = null;
}
export class ConfigMTLSSuccess extends UTSObject {
code!: number;
}
type ConfigMTLSSuccessCallback = (result: ConfigMTLSSuccess) => void;
class ConfigMTLSFail extends UTSObject {
code!: number;
}
type ConfigMTLSFailCallback = (result: ConfigMTLSFail) => void;
type ConfigMTLSComplete = Object;
type ConfigMTLSCompleteCallback = (result: ConfigMTLSComplete) => void;
export class ConfigMTLSOptions extends UTSObject {
certificates!: Certificate[];
success: ConfigMTLSSuccessCallback | null = null;
fail: ConfigMTLSFailCallback | null = null;
complete: ConfigMTLSCompleteCallback | null = null;
}
interface IUniRequestEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function | null) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
interface IRequestTask {
abort: Function;
onHeadersReceived: Function;
offHeadersReceived: Function;
}
interface IUniUploadFileEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function | null) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
interface IUploadTask {
abort: Function;
onHeadersReceived: Function;
offHeadersReceived: Function;
onProgressUpdate: Function;
offProgressUpdate: Function;
}
interface IUniDownloadFileEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function | null) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
interface IDownloadTask {
abort: Function;
onHeadersReceived: Function;
offHeadersReceived: Function;
onProgressUpdate: Function;
offProgressUpdate: Function;
}
export interface UniOAuthProvider extends UniProvider {
login(options: LoginOptions): void;
getUserInfo(options: GetUserInfoOptions): void;
}
export type Login = (options: LoginOptions) => void;
class AppleLoginAppleInfo extends UTSObject {
authorizationCode: string | null = null;
fullName: Object | null = null;
identityToken: string | null = null;
realUserStatus: number | null = null;
user: string | null = null;
}
export class LoginSuccess extends UTSObject {
errMsg!: string;
authResult!: Object;
code!: string;
anonymousCode: string | null = null;
authCode: string | null = null;
authErrorScope: Object | null = null;
authSucessScope: (string[]) | null = null;
appleInfo: AppleLoginAppleInfo | null = null;
}
type LoginSuccessCallback = (result: LoginSuccess) => void;
export type LoginFail = IUniError;
type LoginFailCallback = (result: LoginFail) => void;
type LoginComplete = Object;
type LoginCompleteCallback = (result: LoginComplete) => void;
export class LoginOptions extends UTSObject {
provider: 'weixin' | 'qq' | 'sinaweibo' | 'xiaomi' | 'apple' | 'univerify' | 'huawei' | null = null;
scopes: Object | null = null;
timeout: number | null = null;
univerifyStyle: UniverifyStyle | null = null;
onlyAuthorize: boolean | null = null;
success: LoginSuccessCallback | null = null;
fail: LoginFailCallback | null = null;
complete: LoginCompleteCallback | null = null;
}
class UniverifyIconStyles extends UTSObject {
path!: string;
width: string | null = null;
height: string | null = null;
}
class UniverifyPhoneNumStyles extends UTSObject {
color: string | null = null;
fontSize: string | null = null;
}
class UniverifySloganStyles extends UTSObject {
color: string | null = null;
fontSize: string | null = null;
}
class UniverifyAuthButtonStyles extends UTSObject {
normalColor: string | null = null;
highlightColor: string | null = null;
disabledColor: string | null = null;
width: string | null = null;
height: string | null = null;
textColor: string | null = null;
title: string | null = null;
borderRadius: string | null = null;
}
class UniverifyOtherButtonStyles extends UTSObject {
visible: boolean | null = null;
normalColor: string | null = null;
highlightColor: string | null = null;
width: string | null = null;
height: string | null = null;
textColor: string | null = null;
title: string | null = null;
borderWidth: string | null = null;
borderColor: string | null = null;
borderRadius: string | null = null;
}
class UniverifyPrivacyItemStyles extends UTSObject {
url!: string;
title!: string;
}
class UniverifyPrivacyTermsStyles extends UTSObject {
defaultCheckBoxState: boolean | null = null;
textColor: string | null = null;
termsColor: string | null = null;
prefix: string | null = null;
suffix: string | null = null;
fontSize: string | null = null;
privacyItems: (UniverifyPrivacyItemStyles[]) | null = null;
}
class UniVerifyButtonListItem extends UTSObject {
provider!: string;
iconPath!: string;
}
class UniVerifyButtonsStyles extends UTSObject {
iconWidth: string | null = null;
list!: UniVerifyButtonListItem[];
}
class UniverifyStyle extends UTSObject {
fullScreen: boolean | null = null;
backgroundColor: string | null = null;
backgroundImage: string | null = null;
icon: UniverifyIconStyles | null = null;
phoneNum: UniverifyPhoneNumStyles | null = null;
slogan: UniverifySloganStyles | null = null;
authButton: UniverifyAuthButtonStyles | null = null;
otherLoginButton: UniverifyOtherButtonStyles | null = null;
privacyTerms: UniverifyPrivacyTermsStyles | null = null;
buttons: UniVerifyButtonsStyles | null = null;
}
export type GetUserInfo = (options: GetUserInfoOptions) => void;
export class UserInfo extends UTSObject {
nickName!: string;
openId: string | null = null;
avatarUrl!: string;
}
export class GetUserInfoSuccess extends UTSObject {
userInfo!: UserInfo;
rawData: string | null = null;
signature: string | null = null;
encryptedData: string | null = null;
iv: string | null = null;
errMsg!: string;
}
type GetUserInfoSuccessCallback = (result: GetUserInfoSuccess) => void;
export type GetUserInfoFail = IUniError;
type GetUserInfoFailCallback = (result: GetUserInfoFail) => void;
type GetUserInfoComplete = Object;
type GetUserInfoCompleteCallback = (result: GetUserInfoComplete) => void;
export class GetUserInfoOptions extends UTSObject {
provider: 'weixin' | 'qq' | 'sinaweibo' | 'xiaomi' | 'apple' | 'huawei' | null = null;
withCredentials: boolean | null = null;
lang: string | null = null;
timeout: number | null = null;
success: GetUserInfoSuccessCallback | null = null;
fail: GetUserInfoFailCallback | null = null;
complete: GetUserInfoCompleteCallback | null = null;
}
export type OpenAppAuthorizeSetting = (options: OpenAppAuthorizeSettingOptions) => void;
export class OpenAppAuthorizeSettingSuccess extends UTSObject {
errMsg!: string;
}
type OpenAppAuthorizeSettingSuccessCallback = (result: OpenAppAuthorizeSettingSuccess) => void;
class OpenAppAuthorizeSettingFail extends UTSObject {
errMsg!: string;
}
type OpenAppAuthorizeSettingFailCallback = (result: OpenAppAuthorizeSettingFail) => void;
class OpenAppAuthorizeSettingComplete extends UTSObject {
errMsg!: string;
}
type OpenAppAuthorizeSettingCompleteCallback = (result: OpenAppAuthorizeSettingComplete) => void;
export class OpenAppAuthorizeSettingOptions extends UTSObject {
success: OpenAppAuthorizeSettingSuccessCallback | null = null;
fail: OpenAppAuthorizeSettingFailCallback | null = null;
complete: OpenAppAuthorizeSettingCompleteCallback | null = null;
}
export class OpenDocumentSuccess extends UTSObject {
}
export class OpenDocumentFail extends UTSObject {
}
type OpenDocumentSuccessCallback = (res: OpenDocumentSuccess) => void;
type OpenDocumentFailCallback = (res: OpenDocumentFail) => void;
type OpenDocumentCompleteCallback = (res: Object) => void;
type OpenDocumentSupportedTypes = 'doc' | 'xls' | 'ppt' | 'pdf' | 'docx' | 'xlsx' | 'pptx';
export class OpenDocumentOptions extends UTSObject {
filePath!: string;
fileType: OpenDocumentSupportedTypes | null = null;
success: OpenDocumentSuccessCallback | null = null;
fail: OpenDocumentFailCallback | null = null;
complete: OpenDocumentCompleteCallback | null = null;
}
type OpenDocument = (options?: OpenDocumentOptions | null) => void;
export interface UniPaymentProvider extends UniProvider {
requestPayment(options: RequestPaymentOptions): void;
}
type RequestPaymentErrorCode = 700600 | 701100 | 701110 | 700601 | 700602 | 700603 | 700000 | 700604 | 700605 | 700607 | 700608 | 700800 | 700801;
export type RequestPayment = (options: RequestPaymentOptions) => void;
export class RequestPaymentSuccess extends UTSObject {
data: object | null = null;
}
type RequestPaymentSuccessCallback = (result: RequestPaymentSuccess) => void;
export type RequestPaymentFail = IRequestPaymentFail;
type RequestPaymentFailCallback = (result: RequestPaymentFail) => void;
type RequestPaymentComplete = Object;
interface IRequestPaymentFail extends IUniError {
errCode: RequestPaymentErrorCode;
}
type RequestPaymentCompleteCallback = (result: RequestPaymentComplete) => void;
export class RequestPaymentOptions extends UTSObject {
provider!: string;
orderInfo!: string;
success: RequestPaymentSuccessCallback | null = null;
fail: RequestPaymentFailCallback | null = null;
complete: RequestPaymentCompleteCallback | null = null;
}
type PromptErrorCode = 1 | 1001;
interface IPromptError extends IUniError {
errCode: PromptErrorCode;
}
class ShowToastSuccess extends UTSObject {
}
type ShowToastFail = IPromptError;
type ShowToastSuccessCallback = (res: ShowToastSuccess) => void;
type ShowToastFailCallback = (res: ShowToastFail) => void;
type ShowToastCompleteCallback = (res: Object) => void;
type Icon = "success" | "error" | "fail" | "exception" | "loading" | "none";
type ShowToastPosition = "top" | "center" | "bottom";
class ShowToastOptions extends UTSObject {
title!: string;
icon: Icon | null = null;
image: string.ImageURIString | null = null;
mask: boolean | null = null;
duration: number | null = null;
position: ShowToastPosition | null = null;
success: ShowToastSuccessCallback | null = null;
fail: ShowToastFailCallback | null = null;
complete: ShowToastCompleteCallback | null = null;
}
type ShowToast = (options: ShowToastOptions) => void;
type HideToast = () => void;
class ShowLoadingSuccess extends UTSObject {
}
type ShowLoadingFail = IPromptError;
type ShowLoadingSuccessCallback = (res: ShowLoadingSuccess) => void;
type ShowLoadingFailCallback = (res: ShowLoadingFail) => void;
type ShowLoadingCompleteCallback = (res: Object) => void;
class ShowLoadingOptions extends UTSObject {
title!: string;
mask: boolean | null = null;
success: ShowLoadingSuccessCallback | null = null;
fail: ShowLoadingFailCallback | null = null;
complete: ShowLoadingCompleteCallback | null = null;
}
type ShowLoading = (options: ShowLoadingOptions) => void;
type HideLoading = () => void;
class ShowModalSuccess extends UTSObject {
confirm!: boolean;
cancel!: boolean;
content: string | null = null;
}
type ShowModalFail = IPromptError;
type ShowModalSuccessCallback = (res: ShowModalSuccess) => void;
type ShowModalFailCallback = (res: ShowModalFail) => void;
type ShowModalCompleteCallback = (res: Object) => void;
class ShowModalOptions extends UTSObject {
title: string | null = null;
content: string | null = null;
showCancel: boolean | null = true;
cancelText: string | null = null;
cancelColor: string.ColorString | null = null;
confirmText: string | null = null;
confirmColor: string.ColorString | null = null;
editable: boolean | null = false;
placeholderText: string | null = null;
success: ShowModalSuccessCallback | null = null;
fail: ShowModalFailCallback | null = null;
complete: ShowModalCompleteCallback | null = null;
}
type ShowModal = (options: ShowModalOptions) => void;
class ShowActionSheetSuccess extends UTSObject {
tapIndex!: number;
}
class Popover extends UTSObject {
top!: number;
left!: number;
width!: number;
height!: number;
}
type ShowActionSheetFail = IPromptError;
type ShowActionSheetSuccessCallback = (res: ShowActionSheetSuccess) => void;
type ShowActionSheetFailCallback = (res: ShowActionSheetFail) => void;
type ShowActionSheetCompleteCallback = (res: Object) => void;
class ShowActionSheetOptions extends UTSObject {
title: string | null = null;
alertText: string | null = null;
itemList!: string[];
itemColor: string.ColorString | null = null;
popover: Popover | null = null;
success: ShowActionSheetSuccessCallback | null = null;
fail: ShowActionSheetFailCallback | null = null;
complete: ShowActionSheetCompleteCallback | null = null;
}
type ShowActionSheet = (options: ShowActionSheetOptions) => void;
interface IShowLoadingOptions {
title: string;
mask: boolean;
}
interface IHideLoadingOptions {
}
interface IHideLoadingSuccess {
}
type PullDownRefreshErrorCode = 4;
interface StartPullDownRefreshFail extends IUniError {
errCode: PullDownRefreshErrorCode;
}
export class StartPullDownRefreshOptions extends UTSObject {
success: StartPullDownRefreshSuccessCallback | null = null;
fail: StartPullDownRefreshFailCallback | null = null;
complete: StartPullDownRefreshCompleteCallback | null = null;
}
export type StartPullDownRefreshSuccess = AsyncApiSuccessResult;
type StartPullDownRefreshSuccessCallback = (result: StartPullDownRefreshSuccess) => void;
type StartPullDownRefreshFailCallback = (result: StartPullDownRefreshFail) => void;
type StartPullDownRefreshComplete = AsyncApiResult;
type StartPullDownRefreshCompleteCallback = (result: StartPullDownRefreshComplete) => void;
type StartPullDownRefresh = (options: StartPullDownRefreshOptions) => void;
type StopPullDownRefresh = () => void;
export type Rpx2px = (number: number) => number;
export class ScanCodeSuccess extends UTSObject {
result!: string;
scanType!: string;
}
export class ScanCodeFail extends UTSObject {
}
type ScanCodeSuccessCallback = (res: ScanCodeSuccess) => void;
type ScanCodeFailCallback = (res: ScanCodeFail) => void;
type ScanCodeCompleteCallback = (res: Object) => void;
type ScanCodeSupportedTypes = 'barCode' | 'qrCode' | 'datamatrix' | 'pdf417';
export class ScanCodeOptions extends UTSObject {
onlyFromCamera: boolean | null = null;
scanType: ScanCodeSupportedTypes[] | null = null;
success: ScanCodeSuccessCallback | null = null;
fail: ScanCodeFailCallback | null = null;
complete: ScanCodeCompleteCallback | null = null;
}
type ScanCode = (options?: ScanCodeOptions | null) => void;
type UniScanOptionsTypes = 'barCode' | 'qrCode' | 'datamatrix' | 'pdf417';
type UniScanResultTypes = "QR_CODE" | "AZTEC" | "CODABAR" | "CODE_39" | "CODE_93" | "CODE_128" | "DATA_MATRIX" | "EAN_8" | "EAN_13" | "ITF" | "MAXICODE" | "PDF_417" | "RSS_14" | "RSS_EXPANDED" | "UPC_A" | "UPC_E" | "UPC_EAN_EXTENSION" | "WX_CODE" | "CODE_25";
type HarmonyScanResultTypes = scanCore.ScanType.AZTEC_CODE | scanCore.ScanType.CODABAR_CODE | scanCore.ScanType.CODE128_CODE | scanCore.ScanType.CODE39_CODE | scanCore.ScanType.CODE93_CODE | scanCore.ScanType.DATAMATRIX_CODE | scanCore.ScanType.EAN13_CODE | scanCore.ScanType.EAN8_CODE | scanCore.ScanType.ITF14_CODE | scanCore.ScanType.MULTIFUNCTIONAL_CODE | scanCore.ScanType.PDF417_CODE | scanCore.ScanType.QR_CODE | scanCore.ScanType.UPC_A_CODE | scanCore.ScanType.UPC_E_CODE;
export class ShareWithSystemSuccess extends UTSObject {
}
export type ShareWithSystemFail = IShareWithSystemFail;
interface IShareWithSystemFail extends IUniError {
errCode: ShareWithSystemErrorCode;
}
type ShareWithSystemErrorCode = 1310600 | 1310601 | 1310602 | 1310603 | 1310604 | 1310605 | 1310606 | 1310607;
type ShareWithSystemSuccessCallback = (res: ShareWithSystemSuccess) => void;
type ShareWithSystemFailCallback = (res: ShareWithSystemFail) => void;
type ShareWithSystemCallback = (res: Object) => void;
export class ShareWithSystemOptions extends UTSObject {
type: 'text' | 'image' | 'video' | 'audio' | 'file' | null = null;
summary: string | null = null;
href: string | null = null;
imageUrl: string | null = null;
imagePaths: Array<string> | null = null;
videoPaths: Array<string> | null = null;
audioPaths: Array<string> | null = null;
filePaths: Array<string> | null = null;
success: ShareWithSystemSuccessCallback | null = null;
fail: ShareWithSystemFailCallback | null = null;
complete: ShareWithSystemCallback | null = null;
}
export type ShareWithSystem = (options: ShareWithSystemOptions) => void;
export class SetStorageSuccess extends UTSObject {
}
type SetStorageSuccessCallback = (res: SetStorageSuccess) => void;
type SetStorageFailCallback = (res: UniError) => void;
type SetStorageCompleteCallback = (res: Object) => void;
export class SetStorageOptions extends UTSObject {
key!: string;
data!: Object;
success: SetStorageSuccessCallback | null = null;
fail: SetStorageFailCallback | null = null;
complete: SetStorageCompleteCallback | null = null;
}
export type SetStorage = (options: SetStorageOptions) => void;
export type SetStorageSync = (key: string, data: Object) => void;
export class GetStorageSuccess extends UTSObject {
data: Object | null = null;
}
type GetStorageSuccessCallback = (res: GetStorageSuccess) => void;
type GetStorageFailCallback = (res: UniError) => void;
type GetStorageCompleteCallback = (res: Object) => void;
export class GetStorageOptions extends UTSObject {
key!: string;
success: GetStorageSuccessCallback | null = null;
fail: GetStorageFailCallback | null = null;
complete: GetStorageCompleteCallback | null = null;
}
export type GetStorage = (options: GetStorageOptions) => void;
export type GetStorageSync = (key: string) => Object | null;
export class GetStorageInfoSuccess extends UTSObject {
keys!: Array<string>;
currentSize!: number;
limitSize!: number;
}
type GetStorageInfoSuccessCallback = (res: GetStorageInfoSuccess) => void;
type GetStorageInfoFailCallback = (res: UniError) => void;
type GetStorageInfoCompleteCallback = (res: Object) => void;
export class GetStorageInfoOptions extends UTSObject {
success: GetStorageInfoSuccessCallback | null = null;
fail: GetStorageInfoFailCallback | null = null;
complete: GetStorageInfoCompleteCallback | null = null;
}
export type GetStorageInfo = (options: GetStorageInfoOptions) => void;
export type GetStorageInfoSync = () => GetStorageInfoSuccess;
export class RemoveStorageSuccess extends UTSObject {
}
type RemoveStorageSuccessCallback = (res: RemoveStorageSuccess) => void;
type RemoveStorageFailCallback = (res: UniError) => void;
type RemoveStorageCompleteCallback = (res: Object) => void;
export class RemoveStorageOptions extends UTSObject {
key!: string;
success: RemoveStorageSuccessCallback | null = null;
fail: RemoveStorageFailCallback | null = null;
complete: RemoveStorageCompleteCallback | null = null;
}
export type RemoveStorage = (options: RemoveStorageOptions) => void;
export type RemoveStorageSync = (key: string) => void;
export class ClearStorageSuccess extends UTSObject {
}
type ClearStorageSuccessCallback = (res: ClearStorageSuccess) => void;
type ClearStorageFailCallback = (res: UniError) => void;
type ClearStorageCompleteCallback = (res: Object) => void;
export class ClearStorageOptions extends UTSObject {
success: ClearStorageSuccessCallback | null = null;
fail: ClearStorageFailCallback | null = null;
complete: ClearStorageCompleteCallback | null = null;
}
export type ClearStorage = (option?: ClearStorageOptions | null) => void;
export type ClearStorageSync = () => void;
export type ConnectSocket = (options: ConnectSocketOptions) => SocketTask;
export class ConnectSocketSuccess extends UTSObject {
errMsg!: string;
}
type ConnectSocketSuccessCallback = (result: ConnectSocketSuccess) => void;
type ConnectSocketErrorCode = 600009;
interface ConnectSocketFail extends IUniError {
errCode: ConnectSocketErrorCode;
}
type ConnectSocketFailCallback = (result: ConnectSocketFail) => void;
type ConnectSocketComplete = Object;
type ConnectSocketCompleteCallback = (result: ConnectSocketComplete) => void;
export class ConnectSocketOptions extends UTSObject {
url!: string;
header: UTSJSONObject | null = null;
protocols: (string[]) | null = null;
success: ConnectSocketSuccessCallback | null = null;
fail: ConnectSocketFailCallback | null = null;
complete: ConnectSocketCompleteCallback | null = null;
}
class GeneralCallbackResult extends UTSObject {
errMsg!: string;
}
type SendSocketMessageErrorCode = 10001 | 10002 | 602001;
interface SendSocketMessageFail extends IUniError {
errCode: SendSocketMessageErrorCode;
}
export class SendSocketMessageOptions extends UTSObject {
data!: Object;
success: ((result: GeneralCallbackResult) => void) | null = null;
fail: ((result: SendSocketMessageFail) => void) | null = null;
complete: ((result: Object) => void) | null = null;
}
export class CloseSocketOptions extends UTSObject {
code: number | null = null;
reason: string | null = null;
success: ((result: GeneralCallbackResult) => void) | null = null;
fail: ((result: GeneralCallbackResult) => void) | null = null;
complete: ((result: GeneralCallbackResult) => void) | null = null;
}
class OnSocketOpenCallbackResult extends UTSObject {
header!: Object;
}
export class OnSocketMessageCallbackResult extends UTSObject {
data!: Object;
}
export interface SocketTask {
send(options: SendSocketMessageOptions): void;
close(options: CloseSocketOptions): void;
onOpen(callback: (result: OnSocketOpenCallbackResult) => void): void;
onClose(callback: (result: Object) => void): void;
onError(callback: (result: GeneralCallbackResult) => void): void;
onMessage(callback: (result: OnSocketMessageCallbackResult) => void): void;
}
type OnSocketOpenCallback = (result: OnSocketOpenCallbackResult) => void;
type OnSocketOpen = (options: OnSocketOpenCallback) => void;
export class OnSocketErrorCallbackResult extends UTSObject {
errMsg!: string;
}
type OnSocketErrorCallback = (result: OnSocketErrorCallbackResult) => void;
type OnSocketError = (callback: OnSocketErrorCallback) => void;
type SendSocketMessage = (options: SendSocketMessageOptions) => void;
type OnSocketMessageCallback = (result: OnSocketMessageCallbackResult) => void;
type OnSocketMessage = (callback: OnSocketMessageCallback) => void;
type CloseSocket = (options: CloseSocketOptions) => void;
class OnSocketCloseCallbackResult extends UTSObject {
code!: number;
reason!: string;
}
type OnSocketCloseCallback = (result: OnSocketCloseCallbackResult) => void;
type OnSocketClose = (callback: OnSocketCloseCallback) => void;
interface IUniWebsocketEmitter {
on: (eventName: string, callback: Function) => void;
once: (eventName: string, callback: Function) => void;
off: (eventName: string, callback?: Function | null) => void;
emit: (eventName: string, ...args: (Object | undefined | null)[]) => void;
}
interface UniExtApi {
addPhoneContact: AddPhoneContact;
startSoterAuthentication: StartSoterAuthentication;
checkIsSupportSoterAuthentication: CheckIsSupportSoterAuthentication;
checkIsSoterEnrolledInDevice: CheckIsSoterEnrolledInDevice;
chooseMedia: ChooseMedia;
getClipboardData: GetClipboardData;
setClipboardData: SetClipboardData;
createInnerAudioContext: CreateInnerAudioContext;
$on: $On;
$once: $Once;
$off: $Off;
$emit: $Emit;
exit: Exit;
saveFile: SaveFile;
getSavedFileList: GetSavedFileList;
getSavedFileInfo: GetSavedFileInfo;
removeSavedFile: RemoveSavedFile;
getFileInfo: GetFileInfo;
getFileSystemManager: GetFileSystemManager;
getAppAuthorizeSetting: GetAppAuthorizeSetting;
getAppBaseInfo: GetAppBaseInfo;
getBackgroundAudioManager: GetBackgroundAudioManager;
getDeviceInfo: GetDeviceInfo;
getNetworkType: GetNetworkType;
onNetworkStatusChange: OnNetworkStatusChange;
offNetworkStatusChange: OffNetworkStatusChange;
getProvider: GetProvider;
getProviderSync: GetProviderSync;
getRecorderManager: GetRecorderManager;
getSystemInfo: GetSystemInfo;
getSystemInfoSync: GetSystemInfoSync;
getWindowInfo: GetWindowInfo;
getSystemSetting: GetSystemSetting;
hideKeyboard: HideKeyboard;
makePhoneCall: MakePhoneCall;
chooseImage: ChooseImage;
previewImage: PreviewImage;
closePreviewImage: ClosePreviewImage;
getImageInfo: GetImageInfo;
saveImageToPhotosAlbum: SaveImageToPhotosAlbum;
compressImage: CompressImage;
chooseVideo: ChooseVideo;
saveVideoToPhotosAlbum: SaveVideoToPhotosAlbum;
getVideoInfo: GetVideoInfo;
compressVideo: CompressVideo;
chooseFile: ChooseFile;
request: Request<Object>;
uploadFile: UploadFile;
downloadFile: DownloadFile;
configMTLS: ConfigMTLS;
login: Login;
getUserInfo: GetUserInfo;
openAppAuthorizeSetting: OpenAppAuthorizeSetting;
openDocument: OpenDocument;
requestPayment: RequestPayment;
showToast: ShowToast;
hideToast: HideToast;
showLoading: ShowLoading;
hideLoading: HideLoading;
showModal: ShowModal;
showActionSheet: ShowActionSheet;
startPullDownRefresh: StartPullDownRefresh;
stopPullDownRefresh: StopPullDownRefresh;
rpx2px: Rpx2px;
scanCode: ScanCode;
shareWithSystem: ShareWithSystem;
setStorage: SetStorage;
setStorageSync: SetStorageSync;
getStorage: GetStorage;
getStorageSync: GetStorageSync;
getStorageInfo: GetStorageInfo;
getStorageInfoSync: GetStorageInfoSync;
removeStorage: RemoveStorage;
removeStorageSync: RemoveStorageSync;
clearStorage: ClearStorage;
clearStorageSync: ClearStorageSync;
connectSocket: ConnectSocket;
sendSocketMessage: SendSocketMessage;
closeSocket: CloseSocket;
onSocketOpen: OnSocketOpen;
onSocketMessage: OnSocketMessage;
onSocketClose: OnSocketClose;
onSocketError: OnSocketError;
}
export function initUniExtApi() {
const API_ADD_PHONE_CONTACT = 'addPhoneContact';
const AddPhoneContactApiOptions: ApiOptions<AddPhoneContactOptions> = {
formatArgs: new Map<string, ((firstName: string) => string | undefined)>([
[
'firstName',
(firstName: string)=>{
if (!firstName) {
return 'addPhoneContact:fail parameter error: parameter.firstName should not be empty;';
}
return undefined;
}
]
])
};
const AddPhoneContactApiProtocol = new Map<string, ProtocolOptions>([
[
'firstName',
{
type: 'string',
required: true
}
],
[
'photoFilePath',
{
type: 'string'
}
],
[
'nickName',
{
type: 'string'
}
],
[
'lastName',
{
type: 'string'
}
],
[
'middleName',
{
type: 'string'
}
],
[
'remark',
{
type: 'string'
}
],
[
'mobilePhoneNumber',
{
type: 'string'
}
],
[
'weChatNumber',
{
type: 'string'
}
],
[
'addressCountry',
{
type: 'string'
}
],
[
'addressState',
{
type: 'string'
}
],
[
'addressCity',
{
type: 'string'
}
],
[
'addressStreet',
{
type: 'string'
}
],
[
'addressPostalCode',
{
type: 'string'
}
],
[
'organization',
{
type: 'string'
}
],
[
'title',
{
type: 'string'
}
],
[
'workFaxNumber',
{
type: 'string'
}
],
[
'workPhoneNumber',
{
type: 'string'
}
],
[
'hostNumber',
{
type: 'string'
}
],
[
'email',
{
type: 'string'
}
],
[
'url',
{
type: 'string'
}
],
[
'workAddressCountry',
{
type: 'string'
}
],
[
'workAddressState',
{
type: 'string'
}
],
[
'workAddressCity',
{
type: 'string'
}
],
[
'workAddressStreet',
{
type: 'string'
}
],
[
'workAddressPostalCode',
{
type: 'string'
}
],
[
'homeFaxNumber',
{
type: 'string'
}
],
[
'homePhoneNumber',
{
type: 'string'
}
],
[
'homeAddressCountry',
{
type: 'string'
}
],
[
'homeAddressState',
{
type: 'string'
}
],
[
'homeAddressCity',
{
type: 'string'
}
],
[
'homeAddressStreet',
{
type: 'string'
}
],
[
'homeAddressPostalCode',
{
type: 'string'
}
]
]);
const addPhoneContact: AddPhoneContact = defineAsyncApi<AddPhoneContactOptions, AddPhoneContactSuccess>(API_ADD_PHONE_CONTACT, (args: AddPhoneContactOptions, executor: ApiExecutor<AddPhoneContactSuccess>)=>{
UTSHarmony.requestSystemPermission([
'ohos.permission.WRITE_CONTACTS'
], (allRight: boolean)=>{
if (allRight) {
const photoFilePath = args.photoFilePath, _args_nickName = args.nickName, nickName = _args_nickName == null ? '' : _args_nickName, _args_lastName = args.lastName, lastName = _args_lastName == null ? '' : _args_lastName, _args_middleName = args.middleName, middleName = _args_middleName == null ? '' : _args_middleName, _args_firstName = args.firstName, firstName = _args_firstName == null ? '' : _args_firstName, _args_remark = args.remark, remark = _args_remark == null ? '' : _args_remark, _args_mobilePhoneNumber = args.mobilePhoneNumber, mobilePhoneNumber = _args_mobilePhoneNumber == null ? '' : _args_mobilePhoneNumber, _args_addressCountry = args.addressCountry, addressCountry = _args_addressCountry == null ? '' : _args_addressCountry, _args_addressState = args.addressState, addressState = _args_addressState == null ? '' : _args_addressState, _args_addressCity = args.addressCity, addressCity = _args_addressCity == null ? '' : _args_addressCity, _args_addressStreet = args.addressStreet, addressStreet = _args_addressStreet == null ? '' : _args_addressStreet, _args_addressPostalCode = args.addressPostalCode, addressPostalCode = _args_addressPostalCode == null ? '' : _args_addressPostalCode, _args_organization = args.organization, organization = _args_organization == null ? '' : _args_organization, _args_url = args.url, url = _args_url == null ? '' : _args_url, _args_workPhoneNumber = args.workPhoneNumber, workPhoneNumber = _args_workPhoneNumber == null ? '' : _args_workPhoneNumber, _args_workFaxNumber = args.workFaxNumber, workFaxNumber = _args_workFaxNumber == null ? '' : _args_workFaxNumber, _args_hostNumber = args.hostNumber, hostNumber = _args_hostNumber == null ? '' : _args_hostNumber, _args_email = args.email, email = _args_email == null ? '' : _args_email, _args_title = args.title, title = _args_title == null ? '' : _args_title, _args_workAddressCountry = args.workAddressCountry, workAddressCountry = _args_workAddressCountry == null ? '' : _args_workAddressCountry, _args_workAddressState = args.workAddressState, workAddressState = _args_workAddressState == null ? '' : _args_workAddressState, _args_workAddressCity = args.workAddressCity, workAddressCity = _args_workAddressCity == null ? '' : _args_workAddressCity, _args_workAddressStreet = args.workAddressStreet, workAddressStreet = _args_workAddressStreet == null ? '' : _args_workAddressStreet, workAddressPostalCode = args.workAddressPostalCode, _args_homeFaxNumber = args.homeFaxNumber, homeFaxNumber = _args_homeFaxNumber == null ? '' : _args_homeFaxNumber, _args_homePhoneNumber = args.homePhoneNumber, homePhoneNumber = _args_homePhoneNumber == null ? '' : _args_homePhoneNumber, _args_homeAddressCountry = args.homeAddressCountry, homeAddressCountry = _args_homeAddressCountry == null ? '' : _args_homeAddressCountry, _args_homeAddressState = args.homeAddressState, homeAddressState = _args_homeAddressState == null ? '' : _args_homeAddressState, _args_homeAddressCity = args.homeAddressCity, homeAddressCity = _args_homeAddressCity == null ? '' : _args_homeAddressCity, _args_homeAddressStreet = args.homeAddressStreet, homeAddressStreet = _args_homeAddressStreet == null ? '' : _args_homeAddressStreet, _args_homeAddressPostalCode = args.homeAddressPostalCode, homeAddressPostalCode = _args_homeAddressPostalCode == null ? '' : _args_homeAddressPostalCode;
const contactInfo: contact.Contact = {
name: {
givenName: firstName!,
fullName: lastName! + middleName! + firstName!
}
};
if (nickName) {
contactInfo.nickName = {
nickName: nickName!
} as contact.NickName;
}
if (lastName) {
contactInfo.name!.familyName = lastName;
}
if (middleName) {
contactInfo.name!.middleName = middleName;
}
if (email) {
contactInfo.emails = [
{
email: email!,
displayName: '邮箱'
} as contact.Email
];
}
if (photoFilePath) {
contactInfo.portrait = {
uri: photoFilePath
} as contact.Portrait;
}
if (url) {
contactInfo.websites = [
{
website: url
} as contact.Website
];
}
if (remark) {
contactInfo.note = {
noteContent: remark
} as contact.Note;
}
if (organization) {
contactInfo.organization = {
name: organization,
title: title!
} as contact.Organization;
}
const phoneNumbers: contact.PhoneNumber[] = [];
if (homePhoneNumber) {
phoneNumbers.push({
phoneNumber: homePhoneNumber!,
labelId: contact.PhoneNumber.NUM_HOME
} as contact.PhoneNumber);
}
if (mobilePhoneNumber) {
phoneNumbers.push({
phoneNumber: mobilePhoneNumber!,
labelId: contact.PhoneNumber.NUM_MOBILE
} as contact.PhoneNumber);
}
if (homeFaxNumber) {
phoneNumbers.push({
phoneNumber: homeFaxNumber!,
labelId: contact.PhoneNumber.NUM_FAX_HOME
} as contact.PhoneNumber);
}
if (workFaxNumber) {
phoneNumbers.push({
phoneNumber: workFaxNumber!,
labelId: contact.PhoneNumber.NUM_FAX_WORK
} as contact.PhoneNumber);
}
if (workPhoneNumber) {
phoneNumbers.push({
phoneNumber: workPhoneNumber!,
labelId: contact.PhoneNumber.NUM_WORK
} as contact.PhoneNumber);
}
if (hostNumber) {
phoneNumbers.push({
phoneNumber: hostNumber!,
labelId: contact.PhoneNumber.NUM_COMPANY_MAIN
} as contact.PhoneNumber);
}
if (phoneNumbers.length) contactInfo.phoneNumbers = phoneNumbers;
const postalAddresses: contact.PostalAddress[] = [];
if (homeAddressCity || homeAddressCountry || homeAddressPostalCode || homeAddressStreet) {
postalAddresses.push({
city: homeAddressCity!,
country: homeAddressCountry!,
postcode: homeAddressPostalCode!,
street: homeAddressStreet!,
postalAddress: `${homeAddressCountry!}${homeAddressState!}${homeAddressCity!}${homeAddressStreet!}`,
labelId: contact.PostalAddress.ADDR_HOME
} as contact.PostalAddress);
}
if (workAddressCity || workAddressCountry || workAddressPostalCode || workAddressStreet) {
postalAddresses.push({
city: workAddressCity!,
country: workAddressCountry!,
postcode: workAddressPostalCode!,
street: workAddressStreet!,
postalAddress: `${workAddressCountry!}${workAddressState!}${workAddressCity!}${workAddressStreet!}`,
labelId: contact.PostalAddress.ADDR_WORK
} as contact.PostalAddress);
}
if (addressCity || addressCountry || addressPostalCode || addressStreet) {
postalAddresses.push({
city: addressCity!,
country: addressCountry!,
postcode: addressPostalCode!,
street: addressStreet!,
postalAddress: `${addressCountry!}${addressState!}${addressCity!}${addressStreet!}`,
labelId: contact.PostalAddress.CUSTOM_LABEL
} as contact.PostalAddress);
}
if (postalAddresses.length) contactInfo.postalAddresses = postalAddresses;
contact.addContact(UTSHarmony.getUIAbilityContext()!, contactInfo).then((contactId)=>{
executor.resolve(contactId);
}).catch((err: BusinessError)=>{
executor.reject(err.message);
});
} else {
executor.reject('Permission denied');
}
}, ()=>executor.reject('Permission denied'));
}, AddPhoneContactApiProtocol, AddPhoneContactApiOptions) as AddPhoneContact;
const API_START_SOTER_AUTHENTICATION = 'startSoterAuthentication';
const StartSoterAuthenticationApiOptions: ApiOptions<StartSoterAuthenticationOptions> = {
formatArgs: new Map<string, ((value: string) => string | undefined)>([
[
'requestAuthModes',
(value: string)=>{
if (!value.includes('fingerPrint') && !value.includes('facial')) {
return 'requestAuthModes 填写错误';
}
return undefined;
}
]
])
};
const StartSoterAuthenticationApiProtocols = new Map<string, ProtocolOptions>([
[
'requestAuthModes',
{
type: 'array',
required: true
}
],
[
'challenge',
{
type: 'string',
required: true
}
],
[
'authContent',
{
type: 'string'
}
]
]);
const API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE = 'checkIsSoterEnrolledInDevice';
const checkAuthModes: SoterAuthMode[] = [
'fingerPrint',
'facial',
'speech'
];
const CheckIsSoterEnrolledInDeviceApiOptions: ApiOptions<CheckIsSoterEnrolledInDeviceOptions> = {
formatArgs: new Map<string, ((value: string) => string | undefined)>([
[
'checkAuthMode',
(value: string)=>{
if (!checkAuthModes.includes(value as SoterAuthMode)) {
return 'checkAuthMode 填写错误';
}
return undefined;
}
]
])
};
const CheckIsSoterEnrolledInDeviceProtocols = new Map<string, ProtocolOptions>([
[
'checkAuthMode',
{
type: 'string'
}
]
]);
const API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION = 'checkIsSupportSoterAuthentication';
const getErrorMessage = (code: number): string =>{
switch(code){
case 201:
return "权限认证失败";
case 401:
return "参数不正确。可能的一个原因: 强制参数未指定";
case userAuth.UserAuthResultCode.FAIL:
return "认证失败";
case userAuth.UserAuthResultCode.GENERAL_ERROR:
return "操作通用错误";
case userAuth.UserAuthResultCode.CANCELED:
return "操作取消";
case userAuth.UserAuthResultCode.TIMEOUT:
return "操作超时";
case userAuth.UserAuthResultCode.TYPE_NOT_SUPPORT:
return "不支持的认证类型";
case userAuth.UserAuthResultCode.TRUST_LEVEL_NOT_SUPPORT:
return "不支持的认证等级";
case userAuth.UserAuthResultCode.BUSY:
return "忙碌状态";
case userAuth.UserAuthResultCode.LOCKED:
return "认证器已锁定";
case userAuth.UserAuthResultCode.NOT_ENROLLED:
return "用户未录入认证信息";
case userAuth.UserAuthResultCode.CANCELED_FROM_WIDGET:
return "切换到自定义身份验证过程";
case 12500013:
return "系统锁屏密码过期";
default:
return '';
}
};
const getUniErrMsg = (code: number): number =>{
switch(code){
case 201:
return 90002;
case 401:
return 90004;
case userAuth.UserAuthResultCode.FAIL:
return 90009;
case userAuth.UserAuthResultCode.GENERAL_ERROR:
return 90007;
case userAuth.UserAuthResultCode.CANCELED:
return 90008;
case userAuth.UserAuthResultCode.TIMEOUT:
return 90007;
case userAuth.UserAuthResultCode.TYPE_NOT_SUPPORT:
return 90003;
case userAuth.UserAuthResultCode.TRUST_LEVEL_NOT_SUPPORT:
return 90003;
case userAuth.UserAuthResultCode.BUSY:
return 90010;
case userAuth.UserAuthResultCode.LOCKED:
return 90010;
case userAuth.UserAuthResultCode.NOT_ENROLLED:
return 90011;
case userAuth.UserAuthResultCode.CANCELED_FROM_WIDGET:
return userAuth.UserAuthResultCode.CANCELED_FROM_WIDGET;
case 12500013:
return 12500013;
default:
return -1;
}
};
const toUint8Arr = (str: string)=>{
const buffer: number[] = [];
for (let i of str){
const _code: number = i.charCodeAt(0);
if (_code < 0x80) {
buffer.push(_code);
} else if (_code < 0x800) {
buffer.push(0xc0 + (_code >> 6));
buffer.push(0x80 + (_code & 0x3f));
} else if (_code < 0x10000) {
buffer.push(0xe0 + (_code >> 12));
buffer.push(0x80 + (_code >> 6 & 0x3f));
buffer.push(0x80 + (_code & 0x3f));
}
}
return Uint8Array.from(buffer);
};
const startSoterAuthentication: StartSoterAuthentication = defineAsyncApi<StartSoterAuthenticationOptions, StartSoterAuthenticationSuccess>(API_START_SOTER_AUTHENTICATION, (args: StartSoterAuthenticationOptions, executor: ApiExecutor<StartSoterAuthenticationSuccess>)=>{
const authType: userAuth.UserAuthType[] = [];
args.requestAuthModes.forEach((item)=>{
if (item === 'fingerPrint') {
authType.push(userAuth.UserAuthType.FINGERPRINT);
} else if (item === 'facial') {
authType.push(userAuth.UserAuthType.FACE);
}
});
const challengeArr = toUint8Arr(args.challenge ?? '');
const authContent = args.authContent ?? '';
try {
const auth = userAuth.getUserAuthInstance({
challenge: challengeArr,
authType,
authTrustLevel: userAuth.AuthTrustLevel.ATL1
} as userAuth.AuthParam, {
title: authContent
} as userAuth.WidgetParam);
auth.on("result", {
onResult: (result: userAuth.UserAuthResult)=>{
if (result.result === userAuth.UserAuthResultCode.SUCCESS) {
executor.resolve({
errCode: 0,
authMode: result.authType === userAuth.UserAuthType.FINGERPRINT ? 'fingerPrint' : 'facial'
} as StartSoterAuthenticationSuccess);
} else {
const errMsg = getErrorMessage(result.result);
const errCode = getUniErrMsg(result.result);
executor.reject(errMsg, {
errCode
} as ApiError);
}
}
} as userAuth.IAuthCallback);
if (authContent) {
promptAction.showToast({
message: authContent
} as promptAction.ShowToastOptions);
}
auth.start();
} catch (error) {
const code = (error as BusinessError1).code;
executor.reject(getErrorMessage(code), {
errCode: getUniErrMsg(code)
} as ApiError);
}
}, StartSoterAuthenticationApiProtocols, StartSoterAuthenticationApiOptions) as StartSoterAuthentication;
const fingerPrintAvailable = ()=>{
try {
userAuth.getAvailableStatus(userAuth.UserAuthType.FINGERPRINT, userAuth.AuthTrustLevel.ATL1);
return true;
} catch (error) {
if ([
userAuth.UserAuthResultCode.NOT_ENROLLED,
userAuth.UserAuthResultCode.PIN_EXPIRED
].includes((error as BusinessError1).code)) {
return true;
}
return false;
}
};
const faceAvailable = ()=>{
try {
userAuth.getAvailableStatus(userAuth.UserAuthType.FACE, userAuth.AuthTrustLevel.ATL1);
return true;
} catch (error) {
if ([
userAuth.UserAuthResultCode.NOT_ENROLLED,
userAuth.UserAuthResultCode.PIN_EXPIRED
].includes((error as BusinessError1).code)) {
return true;
}
return false;
}
};
const PERMISSIONS = [
'ohos.permission.ACCESS_BIOMETRIC'
];
const checkIsSupportSoterAuthentication: CheckIsSupportSoterAuthentication = defineAsyncApi<CheckIsSupportSoterAuthenticationOptions, CheckIsSupportSoterAuthenticationSuccess>(API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION, (args: CheckIsSupportSoterAuthenticationOptions, executor: ApiExecutor<CheckIsSupportSoterAuthenticationSuccess>)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS, (allRight: boolean)=>{
if (allRight) {
try {
const supportMode: SoterAuthMode[] = [];
if (fingerPrintAvailable()) supportMode.push('fingerPrint');
if (faceAvailable()) supportMode.push('facial');
return executor.resolve({
supportMode,
errMsg: ''
} as CheckIsSupportSoterAuthenticationSuccess);
} catch (error) {
const code = (error as BusinessError1).code;
executor.reject(getErrorMessage(code), {
errCode: getUniErrMsg(code)
} as ApiError);
}
} else {
executor.reject(getErrorMessage(201));
}
}, ()=>{
executor.reject(getErrorMessage(201));
});
}) as CheckIsSupportSoterAuthentication;
const getFingerPrintEnrolledState = ()=>{
userAuth.getEnrolledState(userAuth.UserAuthType.FINGERPRINT);
return true;
};
const getFaceEnrolledState = ()=>{
userAuth.getEnrolledState(userAuth.UserAuthType.FACE);
return true;
};
const harmonyCheckIsSoterEnrolledInDevice = (checkAuthMode: SoterAuthMode): boolean =>{
if (checkAuthMode === 'fingerPrint') {
return getFingerPrintEnrolledState();
} else if (checkAuthMode === 'facial') {
return getFaceEnrolledState();
}
return false;
};
const checkIsSoterEnrolledInDevice: CheckIsSoterEnrolledInDevice = defineAsyncApi<CheckIsSoterEnrolledInDeviceOptions, CheckIsSoterEnrolledInDeviceSuccess>(API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE, (args: CheckIsSoterEnrolledInDeviceOptions, executor: ApiExecutor<CheckIsSoterEnrolledInDeviceSuccess>)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS, (allRight: boolean)=>{
if (allRight) {
try {
const isEnrolled = harmonyCheckIsSoterEnrolledInDevice(args.checkAuthMode);
executor.resolve({
isEnrolled,
errMsg: ''
} as CheckIsSoterEnrolledInDeviceSuccess);
} catch (error) {
const code = (error as BusinessError1).code;
executor.reject(getErrorMessage(code), {
errCode: getUniErrMsg(code)
} as ApiError);
}
} else {
executor.reject(getErrorMessage(201));
}
}, ()=>{
executor.reject(getErrorMessage(201));
});
}, CheckIsSoterEnrolledInDeviceProtocols, CheckIsSoterEnrolledInDeviceApiOptions) as CheckIsSoterEnrolledInDevice;
const API_CHOOSE_MEDIA = 'chooseMedia';
const ChooseMediaApiProtocol = new Map<string, ProtocolOptions>([
[
'count',
{
type: 'number',
required: false
}
],
[
'mediaType',
{
type: 'array',
required: false
}
],
[
'sourceType',
{
type: 'array',
required: false
}
],
[
'maxDuration',
{
type: 'number',
required: false
}
],
[
'camera',
{
type: 'string',
required: false
}
]
]);
const ChooseMediaApiOptions: ApiOptions<ChooseMediaOptions> = {
formatArgs: new Map<string, Function>([
[
'count',
(count: number, params: ChooseMediaOptions)=>{
if (count == null) {
params.count = 9;
}
if (params.count != null && params.count > 9) {
params.count = 9;
}
}
],
[
'mediaType',
(mediaType: string[], params: ChooseMediaOptions)=>{
if (mediaType == null) {
params.mediaType = [
'image',
'video'
];
}
}
],
[
'sourceType',
(sourceType: string[], params: ChooseMediaOptions)=>{
if (sourceType == null) {
params.sourceType = [
'album',
'camera'
];
}
}
],
[
'maxDuration',
(maxDuration: number, params: ChooseMediaOptions)=>{
if (maxDuration == null) {
params.maxDuration = 10;
}
}
],
[
'camera',
(camera: string, params: ChooseMediaOptions)=>{
if (camera == null) {
params.camera = 'back';
}
}
]
])
};
const _getVideoInfo = async (uri: string): Promise<_GetVideoInfoSuccess> =>{
const file = await fs.open(uri, fs.OpenMode.READ_ONLY);
const avMetadataExtractor = await media.createAVMetadataExtractor();
let metadata: media.AVMetadata | null = null;
let size: number = 0;
try {
size = (await fs.stat(file.fd)).size;
avMetadataExtractor.dataSrc = {
fileSize: size,
callback: (buffer: ArrayBuffer, length: number, pos: number | null = null)=>{
return fs.readSync(file.fd, buffer, {
offset: pos,
length
} as ReadOptions);
}
};
metadata = await avMetadataExtractor.fetchMetadata();
} catch (error) {
throw error as Error;
} finally{
await avMetadataExtractor.release();
await fs.close(file);
}
const videoOrientationArr = [
'up',
'right',
'down',
'left'
] as _MediaOrientation[];
return {
size: size,
duration: metadata.duration ? Number(metadata.duration) / 1000 : undefined,
width: metadata.videoWidth ? Number(metadata.videoWidth) : undefined,
height: metadata.videoHeight ? Number(metadata.videoHeight) : undefined,
type: metadata.mimeType,
orientation: metadata.videoOrientation ? videoOrientationArr[Number(metadata.videoOrientation) / 90] : undefined
} as _GetVideoInfoSuccess;
};
const _chooseMedia = async (options: __ChooseMediaOptions): Promise<_chooseMediaSuccessCallbackResult> =>{
const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
const mimeType = options.mimeType;
photoSelectOptions.MIMEType = mimeType;
if (mimeType === photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE) {
photoSelectOptions.maxSelectNumber = 1;
} else {
photoSelectOptions.maxSelectNumber = options.count || 9;
}
photoSelectOptions.isOriginalSupported = options.isOriginalSupported;
photoSelectOptions.isPhotoTakingSupported = !(options.sourceType && !options.sourceType.includes('camera'));
const photoPicker = new photoAccessHelper.PhotoViewPicker();
const photoSelectResult = await photoPicker.select(photoSelectOptions);
const uris = photoSelectResult.photoUris;
if (mimeType !== photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE) {
let realUris: string[] = uris;
return {
tempFiles: realUris.map((uri)=>{
const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
const stat = fs.statSync(file.fd);
fs.closeSync(file);
return {
fileType: 'image',
tempFilePath: uri,
size: stat.size
} as _MediaFile;
})
};
}
const tempFiles: _MediaFile[] = [];
for(let i = 0; i < uris.length; i++){
const uri = uris[i];
const videoInfo = await _getVideoInfo(uri);
tempFiles.push({
fileType: 'video',
tempFilePath: uri,
size: videoInfo.size,
duration: videoInfo.duration,
width: videoInfo.width,
height: videoInfo.height
} as _MediaFile);
}
return {
tempFiles
} as _chooseMediaSuccessCallbackResult;
};
const getHMCameraPosition = (cameraType: CameraPosition)=>{
switch(cameraType){
case 'back':
return camera.CameraPosition.CAMERA_POSITION_BACK;
case 'front':
return camera.CameraPosition.CAMERA_POSITION_FRONT;
default:
return camera.CameraPosition.CAMERA_POSITION_BACK;
}
};
const getCameraPickerMediaTypes = (UniMediaTypes: UNI_MEDIA_TYPE[]): cameraPicker.PickerMediaType[] =>{
let mediaTypes: Array<cameraPicker.PickerMediaType> = [];
if (UniMediaTypes.includes('mix')) {
mediaTypes.push(cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO);
} else {
if (UniMediaTypes.includes('image')) {
mediaTypes.push(cameraPicker.PickerMediaType.PHOTO);
}
if (UniMediaTypes.includes('video')) {
mediaTypes.push(cameraPicker.PickerMediaType.VIDEO);
}
}
return mediaTypes;
};
const _takeCamera = async (args: ChooseMediaOptions, executor: ApiExecutor<ChooseMediaSuccess>)=>{
try {
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: getHMCameraPosition(args?.camera ?? 'back'),
videoDuration: args?.maxDuration ?? 10
};
const mediaTypes = getCameraPickerMediaTypes((args.mediaType ?? []) as UNI_MEDIA_TYPE[]);
const res = await cameraPicker.pick(UTSHarmony.getUIAbilityContext()!, mediaTypes, pickerProfile);
executor.resolve({
type: 'mix',
tempFiles: [
{
tempFilePath: res.resultUri,
fileType: res.mediaType === cameraPicker.PickerMediaType.PHOTO ? 'image' : 'video'
}
]
} as ChooseMediaSuccess);
} catch (error) {
const err = error as BusinessError2;
executor.reject(err.message, {
errCode: err.code
} as ApiError);
}
};
const __chooseMedia = async (args: ChooseMediaOptions, mimeType: photoAccessHelper1.PhotoViewMIMETypes, executor: ApiExecutor<ChooseMediaSuccess>)=>{
if (args.sourceType?.length === 1 && args.sourceType[0] === 'camera') {
_takeCamera(args, executor);
} else {
_chooseMedia({
mimeType,
sourceType: [
"album"
],
count: args.count!,
isOriginalSupported: true
} as __ChooseMediaOptions).then((res)=>{
executor.resolve({
type: 'mix',
tempFiles: res.tempFiles.map((tempFile): ChooseMediaTempFile =>{
if (tempFile.fileType === 'image') {
return {
fileType: tempFile.fileType,
tempFilePath: tempFile.tempFilePath,
size: tempFile.size
} as ChooseMediaTempFile;
}
return {
tempFilePath: tempFile.tempFilePath,
duration: tempFile.duration,
size: tempFile.size,
height: tempFile.height,
width: tempFile.width,
fileType: tempFile.fileType
} as ChooseMediaTempFile;
})
} as ChooseMediaSuccess);
}).catch((err: Error)=>{
executor.reject(err.message);
});
}
};
const chooseMedia: ChooseMedia = defineAsyncApi<ChooseMediaOptions, ChooseMediaSuccess>(API_CHOOSE_MEDIA, async (args: ChooseMediaOptions, executor: ApiExecutor<ChooseMediaSuccess>)=>{
if (args.mediaType?.length === 1 && args.mediaType[0] === 'image') {
__chooseMedia(args, photoAccessHelper1.PhotoViewMIMETypes.IMAGE_TYPE, executor);
return;
}
if (args.mediaType?.length === 1 && args.mediaType[0] === 'video') {
__chooseMedia(args, photoAccessHelper1.PhotoViewMIMETypes.VIDEO_TYPE, executor);
return;
}
if (args.sourceType?.length === 1 && args.sourceType[0] === 'camera') {
_takeCamera(args, executor);
} else {
const lastWindow = UTSHarmony.getCurrentWindow() as window.Window;
const UIContextPromptAction = await lastWindow.getUIContext().getPromptAction();
UIContextPromptAction.showActionMenu({
buttons: [
{
text: '拍摄',
color: '#000000'
},
{
text: '从相册选择',
color: '#000000'
}
]
} as promptAction1.ActionMenuOptions, (err, ref)=>{
let index = ref.index;
if (err) {
executor.reject('cancel');
} else {
if (index === 0) {
_takeCamera(args, executor);
} else if (index === 1) {
__chooseMedia(args, photoAccessHelper1.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE, executor);
}
}
});
}
}, ChooseMediaApiProtocol, ChooseMediaApiOptions) as ChooseMedia;
const API_GET_CLIPBOARD_DATA = 'getClipboardData';
const API_SET_CLIPBOARD_DATA = 'setClipboardData';
const SetClipboardDataApiOptions: ApiOptions<SetClipboardDataOptions> = {
formatArgs: new Map<string, boolean>([
[
'showToast',
true
]
])
};
const SetClipboardDataProtocol = new Map<string, ProtocolOptions>([
[
'data',
{
type: 'string',
required: true
}
],
[
'showToast',
{
type: 'boolean'
}
]
]);
const getString = (callback: ClipboardCallback)=>{
const systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
UTSHarmony.requestSystemPermission([
'ohos.permission.READ_PASTEBOARD'
], (allRight: boolean)=>{
if (allRight) {
const pasteData = systemPasteboard.getDataSync();
try {
const text: string = pasteData.getPrimaryText();
callback({
data: text,
result: 'success'
} as ClipboardCallbackOptions);
} catch (err) {
callback({
data: (err as BusinessError3<void>).message,
result: 'fail'
} as ClipboardCallbackOptions);
}
} else {
callback({
data: 'Permission denied',
result: 'fail'
} as ClipboardCallbackOptions);
}
}, ()=>{
callback({
data: 'Permission denied',
result: 'fail'
} as ClipboardCallbackOptions);
});
};
const setString = (data: string)=>{
const pasteData: pasteboard.PasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, data);
const systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
try {
systemPasteboard.setDataSync(pasteData);
return {
data,
result: 'success'
} as ClipboardCallbackOptions;
} catch (err) {
return {
data: (err as BusinessError3<void>).message,
result: 'fail'
} as ClipboardCallbackOptions;
}
};
const getClipboardData: GetClipboardData = defineAsyncApi<GetClipboardDataOptions, GetClipboardDataSuccess>(API_GET_CLIPBOARD_DATA, (_: GetClipboardDataOptions, res: ApiExecutor<GetClipboardDataSuccess>)=>{
getString((ret: ClipboardCallbackOptions)=>{
if (ret.result === 'success') {
res.resolve({
data: ret.data
} as GetClipboardDataSuccess);
} else {
res.reject('getClipboardData:fail ' + ret.data);
}
});
}) as GetClipboardData;
const setClipboardData: SetClipboardData = defineAsyncApi<SetClipboardDataOptions, SetClipboardDataSuccess>(API_SET_CLIPBOARD_DATA, (options: SetClipboardDataOptions, res: ApiExecutor<SetClipboardDataSuccess>)=>{
const ret = setString(options.data);
if (ret.result === 'success') {
res.resolve();
} else {
res.reject('setClipboardData:fail ' + ret.data);
}
}, SetClipboardDataProtocol, SetClipboardDataApiOptions) as SetClipboardData;
const API_CREATE_INNER_AUDIO_CONTEXT = 'createInnerAudioContext';
const isFileUri = (path: string)=>{
return path && typeof path === 'string' && (path.startsWith('file://') || path.startsWith('datashare://'));
};
const isSandboxPath = (path: string)=>{
return path && typeof path === 'string' && path.startsWith('/data/storage/');
};
const getFdFromUriOrSandBoxPath = (uri: string)=>{
try {
const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
return file.fd;
} catch (error) {
console.info(`[AdvancedAPI] Can not get file from uri: ${uri} `);
}
throw new Error('file is not exist');
};
const callCallbacks = (callbacks: Function[], ...args: Object[])=>{
callbacks.forEach((cb)=>{
typeof cb === 'function' && cb(...args);
});
};
const remoteCallback = (callbacks: Function[], callback: Function)=>{
const index = callbacks.indexOf(callback);
if (index > -1) {
callbacks.splice(index, 1);
}
};
class AudioPlayerError {
errMsg: string;
errCode: number;
constructor(errMsg: string, errCode: number){
this.errMsg = errMsg;
this.errCode = errCode;
}
}
class AudioPlayerCallback {
onCanplayCallbacks: Function[] = [];
onPlayCallbacks: Function[] = [];
onPauseCallbacks: Function[] = [];
onStopCallbacks: Function[] = [];
onEndedCallbacks: Function[] = [];
onTimeUpdateCallbacks: Function[] = [];
onErrorCallbacks: Function[] = [];
onWaitingCallbacks: Function[] = [];
onSeekingCallbacks: Function[] = [];
onSeekedCallbacks: Function[] = [];
constructor(){}
canPlay() {
callCallbacks(this.onCanplayCallbacks);
}
onCanplay(callback: Function) {
this.onCanplayCallbacks.push(callback);
}
offCanplay(callback: Function) {
remoteCallback(this.onCanplayCallbacks, callback);
}
play() {
callCallbacks(this.onPlayCallbacks);
}
onPlay(callback: Function) {
this.onPlayCallbacks.push(callback);
}
offPlay(callback: Function) {
remoteCallback(this.onPlayCallbacks, callback);
}
pause() {
callCallbacks(this.onPauseCallbacks);
}
onPause(callback: Function) {
this.onPauseCallbacks.push(callback);
}
offPause(callback: Function) {
remoteCallback(this.onPauseCallbacks, callback);
}
stop() {
callCallbacks(this.onStopCallbacks);
}
onStop(callback: Function) {
this.onStopCallbacks.push(callback);
}
offStop(callback: Function) {
remoteCallback(this.onStopCallbacks, callback);
}
ended() {
callCallbacks(this.onEndedCallbacks);
}
onEnded(callback: Function) {
this.onEndedCallbacks.push(callback);
}
offEnded(callback: Function) {
remoteCallback(this.onEndedCallbacks, callback);
}
timeUpdate(time: number) {
callCallbacks(this.onTimeUpdateCallbacks, time);
}
onTimeUpdate(callback: Function) {
this.onTimeUpdateCallbacks.push(callback);
}
offTimeUpdate(callback: Function) {
remoteCallback(this.onTimeUpdateCallbacks, callback);
}
error(res: AudioPlayerError) {
callCallbacks(this.onErrorCallbacks, res);
}
onError(callback: Function) {
this.onErrorCallbacks.push(callback);
}
offError(callback: Function) {
remoteCallback(this.onErrorCallbacks, callback);
}
onPrev(callback: Function) {
console.info('ios only');
}
onNext(callback: Function) {
console.info('ios only');
}
waiting() {
callCallbacks(this.onWaitingCallbacks);
}
onWaiting(callback: Function) {
this.onWaitingCallbacks.push(callback);
}
offWaiting(callback: Function) {
remoteCallback(this.onWaitingCallbacks, callback);
}
seeking() {
callCallbacks(this.onSeekingCallbacks);
}
onSeeking(callback: Function) {
this.onSeekingCallbacks.push(callback);
}
offSeeking(callback: Function) {
remoteCallback(this.onSeekingCallbacks, callback);
}
seeked() {
callCallbacks(this.onSeekedCallbacks);
}
onSeeked(callback: Function) {
this.onSeekedCallbacks.push(callback);
}
offSeeked(callback: Function) {
remoteCallback(this.onSeekedCallbacks, callback);
}
}
const AUDIOS: Record<string, InnerAudioContext | undefined> = {};
const AUDIO_PLAYERS: Record<string, media1.AudioPlayer | undefined> = {};
const LOG = (msg: string)=>console.log(`[createInnerAudioContext]: ${msg}`);
class STATE_TYPE {
static IDLE: string = 'idle';
static PLAYING: string = 'playing';
static PAUSED: string = 'paused';
static STOPPED: string = 'stopped';
static ERROR: string = 'error';
}
class AudioPlayer implements InnerAudioContext {
__v_skip: boolean = true;
private audioPlayerCallback: AudioPlayerCallback = new AudioPlayerCallback();
private _volume: number = 1;
private _src: string = '';
private _autoplay: boolean = false;
private _startTime: number = 0;
private _buffered: number = 0;
private _title: string = '';
private audioId: string = '';
private _playbackRate: number = 1;
readonly obeyMuteSwitch: boolean = false;
constructor(audioId: string){
this.audioId = audioId;
this.init();
}
init() {
AUDIO_PLAYERS[this.audioId]?.on('dataLoad', ()=>{
this.audioPlayerCallback.canPlay();
});
AUDIO_PLAYERS[this.audioId]?.on('play', ()=>{
this.audioPlayerCallback.play();
});
AUDIO_PLAYERS[this.audioId]?.on('pause', ()=>{
this.audioPlayerCallback.pause();
});
AUDIO_PLAYERS[this.audioId]?.on('finish', ()=>{
this.audioPlayerCallback.ended();
});
AUDIO_PLAYERS[this.audioId]?.on('timeUpdate', (res)=>{
this.audioPlayerCallback.timeUpdate(res / 1000);
});
AUDIO_PLAYERS[this.audioId]?.on('error', (err)=>{
this.audioPlayerCallback.error(new AudioPlayerError(err.message, err.code));
});
AUDIO_PLAYERS[this.audioId]?.on('bufferingUpdate', (infoType, value)=>{
console.info(`[AdvancedAPI] audioPlayer bufferingUpdate ${infoType} ${value}`);
if (infoType === media1.BufferingInfoType.BUFFERING_PERCENT && value !== 0 && AUDIO_PLAYERS[this.audioId]) {
this._buffered = value;
if ((AUDIO_PLAYERS[this.audioId]!.currentTime / 1000) >= (AUDIO_PLAYERS[this.audioId]!.duration * value / 100000)) {
this.audioPlayerCallback.waiting();
}
}
});
AUDIO_PLAYERS[this.audioId]?.on('audioInterrupt', (InterruptEvent)=>{
console.info('[AdvancedAPI] audioInterrupt:' + JSON.stringify(InterruptEvent));
if (AUDIO_PLAYERS[this.audioId] && InterruptEvent.hintType === audio.InterruptHint.INTERRUPT_HINT_PAUSE) {
AUDIO_PLAYERS[this.audioId]!.pause();
}
});
}
get duration() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return 0;
}
return audioPlayer.duration / 1000;
}
get currentTime() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return 0;
}
return audioPlayer.currentTime / 1000;
}
get paused() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return false;
}
return audioPlayer.state === STATE_TYPE.PAUSED;
}
get loop() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return false;
}
return audioPlayer.loop;
}
set loop(value) {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (audioPlayer) {
audioPlayer.loop = value;
}
}
get volume() {
return this._volume;
}
set volume(value) {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (audioPlayer) {
this._volume = value;
audioPlayer.setVolume(value);
}
}
get src() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return '';
}
return audioPlayer.src;
}
set src(value) {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (typeof value !== 'string') {
this.audioPlayerCallback.error(new AudioPlayerError(`set src: ${value} is not string`, 10004));
return;
}
if (!audioPlayer) {
this.audioPlayerCallback.error(new AudioPlayerError(`player is not exist`, 10001));
return;
}
if (!value || !(value.startsWith('http:') || value.startsWith('https:') || isFileUri(value) || isSandboxPath(value))) {
LOG(`set src: ${value} is invalid`);
return;
}
let path: string = '';
if (value.startsWith('http:') || value.startsWith('https:')) {
path = value;
} else if (isFileUri(value) || isSandboxPath(value)) {
try {
const fd = getFdFromUriOrSandBoxPath(value);
path = `fd://${fd}`;
} catch (error) {
console.error(`${JSON.stringify(error)}`);
}
}
if (audioPlayer.src && path !== audioPlayer.src) {
audioPlayer.reset();
}
AUDIO_PLAYERS[this.audioId]!.src = path;
this._src = value;
if (this._autoplay) {
audioPlayer.play();
if (this._startTime) {
audioPlayer.seek(this._startTime);
}
}
}
get startTime() {
return this._startTime / 1000;
}
set startTime(time: number) {
this._startTime = time * 1000;
}
get autoplay() {
return this._autoplay;
}
set autoplay(flag) {
this._autoplay = flag;
}
get buffered() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) return 0;
return audioPlayer.duration * this._buffered / 100000;
}
set playbackRate(rate: number) {
this.audioPlayerCallback.error(new AudioPlayerError('HarmonyOS Next Audio setting playbackRate is not supported.', -1));
}
get playbackRate() {
return this._playbackRate;
}
play() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return;
}
const state = audioPlayer.state ?? '';
if (![
STATE_TYPE.PAUSED,
STATE_TYPE.STOPPED,
STATE_TYPE.IDLE
].includes(state)) {
return;
}
if (this._src && audioPlayer.src === '') {
this.src = this._src;
}
audioPlayer.play();
}
pause() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return;
}
const state = audioPlayer.state;
if (STATE_TYPE.PLAYING !== state) {
return;
}
audioPlayer.pause();
}
stop() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return;
}
if (![
STATE_TYPE.PAUSED,
STATE_TYPE.PLAYING
].includes(audioPlayer.state)) {
return;
}
audioPlayer.stop();
this.audioPlayerCallback.stop();
audioPlayer.release();
}
seek(position: number) {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return;
}
const state = audioPlayer.state;
if (![
STATE_TYPE.PAUSED,
STATE_TYPE.PLAYING
].includes(state)) {
return;
}
this.audioPlayerCallback.seeking();
audioPlayer.seek(position * 1000);
this.audioPlayerCallback.seeked();
}
destroy() {
const audioPlayer = AUDIO_PLAYERS[this.audioId];
if (!audioPlayer) {
return;
}
audioPlayer.release();
AUDIO_PLAYERS[this.audioId] = undefined;
AUDIOS[this.audioId] = undefined;
}
onCanplay(callback: (result: Object) => void): void {
this.audioPlayerCallback.onCanplay(callback);
}
onPlay(callback: (result: Object) => void): void {
this.audioPlayerCallback.onPlay(callback);
}
onPause(callback: (result: Object) => void): void {
this.audioPlayerCallback.onPause(callback);
}
onStop(callback: (result: Object) => void): void {
this.audioPlayerCallback.onStop(callback);
}
onEnded(callback: (result: Object) => void): void {
this.audioPlayerCallback.onEnded(callback);
}
onTimeUpdate(callback: (result: Object) => void): void {
this.audioPlayerCallback.onTimeUpdate(callback);
}
onError(callback: (result: ICreateInnerAudioContextFail) => void): void {
this.audioPlayerCallback.onError(callback);
}
onWaiting(callback: (result: Object) => void): void {
this.audioPlayerCallback.onWaiting(callback);
}
onSeeking(callback: (result: Object) => void): void {
this.audioPlayerCallback.onSeeking(callback);
}
onSeeked(callback: (result: Object) => void): void {
this.audioPlayerCallback.onSeeked(callback);
}
offCanplay(callback: (result: Object) => void): void {
this.audioPlayerCallback.offCanplay(callback);
}
offPlay(callback: (result: Object) => void): void {
this.audioPlayerCallback.offPlay(callback);
}
offPause(callback: (result: Object) => void): void {
this.audioPlayerCallback.offPause(callback);
}
offStop(callback: (result: Object) => void): void {
this.audioPlayerCallback.offStop(callback);
}
offEnded(callback: (result: Object) => void): void {
this.audioPlayerCallback.offEnded(callback);
}
offTimeUpdate(callback: (result: Object) => void): void {
this.audioPlayerCallback.offTimeUpdate(callback);
}
offError(callback: (result: ICreateInnerAudioContextFail) => void): void {
this.audioPlayerCallback.offError(callback);
}
offWaiting(callback: (result: Object) => void): void {
this.audioPlayerCallback.offWaiting(callback);
}
offSeeking(callback: (result: Object) => void): void {
this.audioPlayerCallback.offSeeking(callback);
}
offSeeked(callback: (result: Object) => void): void {
this.audioPlayerCallback.offSeeked(callback);
}
}
const createAudioInstance = ()=>{
const audioId = `${Date.now()}${Math.random()}`;
AUDIO_PLAYERS[audioId] = media1.createAudioPlayer();
AUDIOS[audioId] = new AudioPlayer(audioId);
return audioId;
};
const createInnerAudioContext: CreateInnerAudioContext = defineSyncApi<InnerAudioContext>(API_CREATE_INNER_AUDIO_CONTEXT, ()=>{
const audioId = createAudioInstance();
return AUDIOS[audioId];
}) as CreateInnerAudioContext;
const API_$_ON = '$on';
const API_$_ONCE = '$once';
const API_$_OFF = '$off';
const API_$_EMIT = '$emit';
const emitterStore = new Map<string, IUniEventEmitter>();
const getEmitter = (): IUniEventEmitter =>{
const mp = getCurrentMP();
const id = mp.id as string;
if (emitterStore.has(id)) {
return emitterStore.get(id) as IUniEventEmitter;
}
const emitter = new Emitter() as IUniEventEmitter;
emitterStore.set(id, emitter);
mp.on('beforeClose', ()=>{
emitterStore.delete(id);
});
return emitter;
};
const $on: $On = defineSyncApi<number>(API_$_ON, (eventName: string, callback: Function)=>{
return getEmitter().on(eventName, callback);
}) as $On;
const $once: $Once = defineSyncApi<number>(API_$_ONCE, (eventName: string, callback: Function)=>{
return getEmitter().once(eventName, callback);
}) as $Once;
const $off: $Off = defineSyncApi<void>(API_$_OFF, (eventName: string, callback: Function)=>{
getEmitter().off(eventName, callback);
}) as $Off;
const $emit: $Emit = defineSyncApi<void>(API_$_EMIT, (eventName: string, ...args: (Object | undefined | null)[])=>{
getEmitter().emit(eventName, ...args);
}) as $Emit;
const API_EXIT = 'exit';
const exit: Exit = defineSyncApi<void>(API_EXIT, ()=>{
UTSHarmony.exit();
}) as Exit;
const API_SAVE_FILE = 'saveFile';
const API_GET_FILE_INFO = 'getFileInfo';
const API_GET_SAVED_FILE_INFO = 'getSavedFileInfo';
const API_GET_SAVED_FILE_LIST = 'getSavedFileList';
const API_REMOVE_SAVED_FILE = 'removeSavedFile';
const getSavedDir = ()=>{
return getEnv().USER_DATA_PATH + '/saved';
};
let savedIndex: [string, number] = [
'0',
0
];
const getSavedFileName = (filePath: string)=>{
const ext = filePath.split('/').pop()?.split('.').slice(1).join('.');
let fileName = Date.now() + '';
if (savedIndex[0] === fileName) {
savedIndex[1]++;
if (savedIndex[1] > 0) {
fileName += '-' + savedIndex[1];
}
} else {
savedIndex[0] = fileName;
savedIndex[1] = 0;
}
if (ext) {
fileName += '.' + ext;
}
return fileName;
};
const getFsPath = (filePath: string)=>{
filePath = getRealPath(filePath) as string;
if (!/^file:/.test(filePath)) {
return filePath;
}
const rawPath = filePath.replace(/^file:\/\//, '');
if (rawPath[0] === '/') {
return rawPath;
}
return filePath;
};
const saveFile: SaveFile = defineAsyncApi<LegacySaveFileOptions, LegacySaveFileSuccess>(API_SAVE_FILE, (options: LegacySaveFileOptions, exec: ApiExecutor<LegacySaveFileSuccess>)=>{
const tempFilePath = getRealPath(options.tempFilePath) as string;
const savedPath = getSavedDir();
if (!fs1.accessSync(savedPath)) {
fs1.mkdirSync(savedPath, true);
}
let srcFile: fs1.File;
try {
srcFile = fs1.openSync(tempFilePath, fs1.OpenMode.READ_ONLY);
} catch (error) {
exec.reject((error as Error).message);
return;
}
const savedFilePath = savedPath + '/' + getSavedFileName(tempFilePath);
fs1.copyFile(srcFile.fd, savedFilePath, (err)=>{
fs1.closeSync(srcFile);
if (err) {
exec.reject(err.message);
} else {
exec.resolve({
savedFilePath
} as LegacySaveFileSuccess);
}
});
}) as SaveFile;
const getSavedFileList: GetSavedFileList = defineAsyncApi<LegacyGetSavedFileListOptions, LegacyGetSavedFileListSuccess>(API_GET_SAVED_FILE_LIST, (options: LegacyGetSavedFileListOptions, exec: ApiExecutor<LegacyGetSavedFileListSuccess>)=>{
const savedPath = getSavedDir();
if (!fs1.accessSync(savedPath)) {
exec.resolve({
fileList: []
} as LegacyGetSavedFileListSuccess);
}
fs1.listFile(savedPath, {} as ListFileOptions, (err, fileList)=>{
if (err) {
exec.reject(err.message);
} else {
exec.resolve({
fileList: fileList.map((filePath: string)=>{
const fullPath = savedPath + '/' + filePath;
const stat = fs1.statSync(fullPath);
if (!stat.isFile()) {
return null;
}
return {
filePath: fullPath,
size: stat.size,
createTime: stat.ctime
} as LegacySavedFileListItem;
}).filter((item)=>!!item)
} as LegacyGetSavedFileListSuccess);
}
});
}) as GetSavedFileList;
const getSavedFileInfo: GetSavedFileInfo = defineAsyncApi<LegacyGetSavedFileInfoOptions, LegacyGetSavedFileInfoSuccess>(API_GET_SAVED_FILE_INFO, (options: LegacyGetSavedFileInfoOptions, exec: ApiExecutor<LegacyGetSavedFileInfoSuccess>)=>{
const savedFilePath = getFsPath(options.filePath);
if (!fs1.accessSync(savedFilePath)) {
exec.reject('file not exist');
return;
}
const stat = fs1.statSync(savedFilePath);
if (!stat.isFile()) {
exec.reject('file not exist');
}
exec.resolve({
size: stat.size,
createTime: stat.ctime
} as LegacyGetSavedFileInfoSuccess);
}) as GetSavedFileInfo;
const removeSavedFile: RemoveSavedFile = defineAsyncApi<LegacyRemoveSavedFileOptions, LegacyRemoveSavedFileSuccess>(API_REMOVE_SAVED_FILE, (options: LegacyRemoveSavedFileOptions, exec: ApiExecutor<LegacyRemoveSavedFileSuccess>)=>{
const savedFilePath = getFsPath(options.filePath);
if (!fs1.accessSync(savedFilePath)) {
exec.reject('file not exist');
return;
}
fs1.unlink(savedFilePath, (err)=>{
if (err) {
exec.reject(err.message);
} else {
exec.resolve();
}
});
}) as RemoveSavedFile;
const SupportedHashAlgorithm = [
'md5',
'sha1'
];
const getFileInfo: GetFileInfo = defineAsyncApi<LegacyGetFileInfoOptions, LegacyGetFileInfoSuccess>(API_GET_FILE_INFO, (options: LegacyGetFileInfoOptions, exec: ApiExecutor<LegacyGetFileInfoSuccess>)=>{
const filePath = getFsPath(options.filePath);
const digestAlgorithm = options.digestAlgorithm && SupportedHashAlgorithm.includes(options.digestAlgorithm) ? options.digestAlgorithm : 'md5';
if (!fs1.accessSync(filePath)) {
exec.reject('file not exist');
return;
}
const stat = fs1.statSync(filePath);
if (!stat.isFile()) {
exec.reject('file not exist');
}
Hash.hash(filePath, digestAlgorithm, (err, hash)=>{
if (err) {
exec.reject(err.message);
} else {
exec.resolve({
size: stat.size,
digest: hash
} as LegacyGetFileInfoSuccess);
}
});
}) as GetFileInfo;
const GET_FILE_SYSTEM_MANAGER = 'getFileSystemManager';
class FileCallback {
successFn?: Function;
failFn?: Function;
completeFn?: Function;
constructor(callback: CallBack = {}){
if (typeof callback.success === 'function') this.successFn = callback.success;
if (typeof callback.fail === 'function') this.failFn = callback.fail;
if (typeof callback.complete === 'function') this.completeFn = callback.complete;
}
success(...args: Object[]) {
if (this.successFn) {
try {
this.successFn(...args);
} catch (err) {
console.error(err);
}
}
if (this.completeFn) {
try {
this.completeFn(...args);
} catch (err) {
console.error(err);
}
}
}
fail(...args: Object[]) {
if (this.failFn) {
try {
this.failFn(...args);
} catch (err) {
console.error(err);
}
}
if (this.completeFn) {
try {
this.completeFn(...args);
} catch (err) {
console.error(err);
}
}
}
}
const FileSystemManagerUniErrorSubject = 'uni-fileSystemManager';
const FileSystemManagerUniErrors: Map<FileSystemManagerErrorCode, string> = new Map([
[
1200002,
'Type error. only support base64 / utf-8'
],
[
1300002,
'No such file or directory'
],
[
1300013,
'Permission denied'
],
[
1300021,
'Is a directory'
],
[
1300022,
'Invalid argument'
],
[
1300066,
'Directory not empty'
],
[
1301003,
'Illegal operation on a directory'
],
[
1301005,
'File already exists'
],
[
1300201,
'System error'
],
[
1300202,
'The maximum size of the file storage limit is exceeded'
],
[
1301111,
'Brotli decompress fail'
],
[
1302003,
'Invalid flag'
],
[
1300009,
'Bad file descriptor'
],
[
1300010,
'Try again'
],
[
1300011,
'Bad address'
],
[
1300012,
'Operation would block'
],
[
1300014,
'Network is unreachable'
],
[
1300015,
'Unknown error'
],
[
1300016,
'Not a directory'
],
[
1300017,
'Text file busy'
],
[
1300018,
'File too large'
],
[
1300019,
'Read-only file system'
],
[
1300020,
'File name too long'
]
]);
class FileSystemManagerFailImpl extends UniError implements IFileSystemManagerFail {
errCode: FileSystemManagerErrorCode;
constructor(errCode: FileSystemManagerErrorCode){
super();
this.errSubject = FileSystemManagerUniErrorSubject;
this.errCode = errCode;
this.errMsg = FileSystemManagerUniErrors.get(errCode) ?? "";
}
}
let type = new util.types();
const modeReflect: ModeReflect = {
'ax': 'a',
'ax+': 'a+',
'wx': 'w',
'wx+': 'w+'
};
const ENCODING = [
'utf8',
'utf-8',
'ascii',
'base64',
'binary',
'hex',
'ucs2',
'ucs-2',
'utf16le',
'utf-16le',
'latin1'
];
const getFileTypeMode = (stat: fs2.Stat): number =>{
if (stat.isBlockDevice()) {
return 0o060000;
}
if (stat.isCharacterDevice()) {
return 0o020000;
}
if (stat.isDirectory()) {
return 0o040000;
}
if (stat.isFIFO()) {
return 0o010000;
}
if (stat.isFile()) {
return 0o100000;
}
if (stat.isSocket()) {
return 0o140000;
}
if (stat.isSymbolicLink()) {
return 0o120000;
}
return 0;
};
const getOpenMode = (flag: string): number | null =>{
switch(flag){
case 'a':
return fs2.OpenMode.CREATE | fs2.OpenMode.APPEND;
case 'a+':
return fs2.OpenMode.CREATE | fs2.OpenMode.READ_WRITE | fs2.OpenMode.APPEND;
case 'as':
return fs2.OpenMode.SYNC | fs2.OpenMode.CREATE | fs2.OpenMode.APPEND;
case 'as+':
return fs2.OpenMode.SYNC | fs2.OpenMode.CREATE | fs2.OpenMode.READ_WRITE | fs2.OpenMode.APPEND;
case 'r':
return fs2.OpenMode.READ_ONLY;
case 'r+':
return fs2.OpenMode.READ_WRITE;
case 'w':
return fs2.OpenMode.CREATE | fs2.OpenMode.WRITE_ONLY | fs2.OpenMode.TRUNC;
case 'w+':
return fs2.OpenMode.CREATE | fs2.OpenMode.READ_WRITE | fs2.OpenMode.TRUNC;
}
return null;
};
const transformErrorCode = (errCode: number): FileSystemManagerErrorCode =>{
switch(errCode){
case 13900012:
case 13900001:
return 1300013;
case 13900002:
return 1300002;
case 13900004:
return 1300201;
case 13900005:
return 1301003;
case 13900008:
return 1300009;
case 13900010:
return 1300010;
case 13900013:
return 1300011;
case 13900018:
return 1300016;
case 13900019:
return 1300021;
case 13900020:
return 1300022;
case 13900023:
return 1300017;
case 13900024:
return 1300018;
case 13900027:
return 1300019;
case 13900030:
return 1300020;
case 13900033:
return 1300021;
case 13900034:
return 1300012;
case 13900042:
return 1300013;
case 13900044:
return 1300014;
}
return 1300201;
};
const isString = (data: DataType | null = null): boolean =>{
return typeof data === 'string';
};
const isFunction = (data: DataType | null = null): boolean =>{
return typeof data === 'function';
};
const isNull = (data: DataType | null = null): boolean =>{
return data === null;
};
const isUndefined = (data: DataType | null = null): boolean =>{
return typeof data === 'undefined';
};
const isArray = (data: DataType | null = null): boolean =>{
return Array.isArray(data);
};
const isNumber = (data: DataType | null = null): boolean =>{
return typeof data === 'number' && !Number.isNaN(data) && Number.isFinite(data);
};
const isBoolean = (data: DataType | null = null): boolean =>{
return typeof data === 'boolean';
};
const isArrayBuffer = (data: DataType | null = null): boolean =>{
return type.isAnyArrayBuffer(data as object);
};
const checkSingleDataType = (data: DataType, dataType: string)=>{
let result = false;
switch(dataType){
case 'string':
result = isString(data);
break;
case 'number':
result = isNumber(data);
break;
case 'boolean':
result = isBoolean(data);
break;
case 'function':
result = isFunction(data);
break;
case 'arraybuffer':
result = isArrayBuffer(data);
break;
case 'array':
result = isArray(data);
break;
case 'null':
result = isNull(data);
break;
case 'undefined':
result = isUndefined(data);
break;
}
return result;
};
const checkDataType = (data: DataType, isRequired: boolean, dataType: string, customCheck: ((data: DataType) => boolean) | null = null): boolean =>{
let result = false;
try {
if (isRequired && (isNull(data) || isUndefined(data))) {
throw new Error('The param data is required');
}
if (!isString(dataType) && !isArray(dataType)) {
throw new Error('The param dataType should be a String or an Array');
}
if (customCheck != null && typeof customCheck !== 'function') {
throw new Error('If customCheck exist,it should be a Function');
}
if (!isRequired && (isNull(data) || isUndefined(data))) {
return true;
}
result = checkSingleDataType(data as DataType, dataType);
if (result && typeof customCheck === 'function') {
result = customCheck!(data);
}
} catch (error) {
console.log(error);
return false;
}
return result;
};
const checkPathExistence = (methodName: string, pathName: string, path: string): CustomValidReturn | CustomValidReturnValid =>{
const errMsg = `${methodName}: fail ${pathName}`;
let isValid = false;
if (!checkDataType(path, true, 'string')) {
return {
isValid,
err: getParameterError(errMsg)
} as CustomValidReturn;
}
if (path === '') {
return {
isValid,
err: getPermissionError(errMsg) as IFileSystemManagerFail
} as CustomValidReturn;
}
if (!fs2.accessSync(path)) {
return {
isValid,
err: getNoSuchFileOrDirectoryError(errMsg) as IFileSystemManagerFail
} as CustomValidReturn;
}
return {
isValid: true
} as CustomValidReturnValid;
};
const ohosRead = (filePath: string, sizeOfNewArrayBuffer: number, cb: FileCallback)=>{
const file = fs2.openSync(filePath, fs2.OpenMode.READ_ONLY);
const buf = new ArrayBuffer(sizeOfNewArrayBuffer);
fs2.read(file.fd, buf).then((readLen)=>{
cb.success({
data: buf
} as ReadFileSuccessResult);
}).catch((err: BusinessError4)=>{
cb.fail(new FileSystemManagerFailImpl(transformErrorCode(err.code)) as ApiError);
}).finally(()=>{
fs2.closeSync(file);
});
};
const ohosReadText = (filePath: string, option: ReadTextOptions, cb: FileCallback)=>{
fs2.readText(filePath, option).then((str)=>{
cb.success({
data: str
} as ReadFileSuccessResult);
}).catch((err: BusinessError4)=>{
cb.fail(new FileSystemManagerFailImpl(transformErrorCode(err.code)) as ApiError);
});
};
const obtainUpperPath = (inputPath: string): ObtainUpperPathReturn =>{
let index = inputPath.lastIndexOf('/');
let upperPath = inputPath.substring(0, index);
return {
index,
upperPath
} as ObtainUpperPathReturn;
};
const obtainFileName = (inputPath: string): ObtainFileNameReturn =>{
let index = inputPath.lastIndexOf('/');
let fileName = inputPath.substring(index);
if (inputPath.endsWith('/')) {
fileName = inputPath.substring(inputPath.lastIndexOf("/", inputPath.length - 2) + 1, inputPath.length - 1);
}
return {
index,
fileName
} as ObtainFileNameReturn;
};
const checkFd = (methodName: string, fd: string): CheckFd | CheckFdErr =>{
const errMsg = `${methodName}: fail`;
if (!checkDataType(fd, true, 'string')) {
return {
isValid: false,
fd: 0,
err: getParameterError(errMsg)
};
}
const transFdToNum = Number(fd);
if (isNaN(transFdToNum)) {
return {
isValid: false,
fd: 0,
err: getParameterError(errMsg)
};
}
return {
isValid: true,
fd: transFdToNum
};
};
const checkPath = (methodName: string, pathName: string, path: string): CustomValidReturn | CustomValidReturnValid =>{
const errMsg = `${methodName}: fail ${pathName}`;
let isValid = false;
if (!checkDataType(path, true, 'string')) {
return {
isValid,
err: getParameterError(errMsg)
};
}
if (path === '') {
return {
isValid,
err: getPermissionError(errMsg)
};
}
return {
isValid: true
};
};
const checkPathSync = (methodName: string, pathName: string, path: string): CustomValidReturn | CustomValidReturnValid =>{
const errMsg = `${methodName}: fail ${pathName}`;
let isValid = false;
if (path === '' || !checkDataType(path, true, 'string')) {
return {
isValid,
err: getParameterError(errMsg)
};
}
return {
isValid: true
};
};
const checkPathExistenceSync = (methodName: string, pathName: string, path: string): CustomValidReturn | CustomValidReturnValid =>{
const errMsg = `${methodName}: fail ${pathName}`;
let isValid = false;
if (path === '' || !checkDataType(path, true, 'string')) {
return {
isValid,
err: getParameterError(errMsg)
};
}
if (!fs2.accessSync(path)) {
return {
isValid,
err: getNoSuchFileOrDirectoryError(errMsg)
};
}
return {
isValid: true
};
};
const checkEncoding = (methodName: string, encoding: string | null = null): CheckEncodingReturn =>{
let isValid = false;
if (encoding === null || !checkDataType(encoding, false, 'string')) {
return {
errMsg: `${methodName}: fail invalid encoding: ${encoding}`,
isValid
} as CheckEncodingReturn;
}
if (encoding !== '' && encoding !== undefined) {
if (!ENCODING.includes(encoding)) {
return {
errMsg: `${methodName}: fail Unknown encoding: ${encoding}`,
isValid
} as CheckEncodingReturn;
}
if (encoding !== 'utf-8' && encoding !== 'utf8') {
return {
errMsg: `${methodName}: fail, The encoding is valid, but is not supported currently: ${encoding}`,
isValid
} as CheckEncodingReturn;
}
}
return {
isValid: true,
errMsg: ''
};
};
const isFileUri1 = (path: string)=>{
return path && typeof path === 'string' && (path.startsWith('file://') || path.startsWith('datashare://'));
};
class SecurityBase {
static rsa(algName: string, blob: cryptoFramework.DataBlob): Promise<Uint8Array> {
return new Promise<Uint8Array>(async (resolve, reject)=>{
let md: cryptoFramework.Md;
try {
md = cryptoFramework.createMd(algName);
await md.update(blob);
const mdOutput = await md.digest();
resolve(mdOutput.data);
} catch (error) {
console.error(`rsa fail error code: ${(error as BusinessError4).code}, message is: ${(error as BusinessError4).message}`);
reject(error);
}
});
}
}
const getApiError = (errCode: number, errMsg: string | null = null): FileSystemManagerApiError =>{
return wrapErrMsg(new FileSystemManagerFailImpl(transformErrorCode(errCode)), errMsg) as FileSystemManagerApiError;
};
const wrapErrMsg = (err: IFileSystemManagerFail, errMsg: string | null = null): IFileSystemManagerFail =>{
if (errMsg) {
err.errMsg = `${errMsg} ${err.errMsg}`;
}
return err;
};
const getParameterError = (errMsg: string | null = null): IFileSystemManagerFail =>{
return getApiError(1300022, errMsg) as IFileSystemManagerFail;
};
const getPermissionError = (errMsg: string | null = null): IFileSystemManagerFail =>{
return getApiError(1300013, errMsg) as IFileSystemManagerFail;
};
const getNoSuchFileOrDirectoryError = (errMsg: string | null = null): IFileSystemManagerFail =>{
return getApiError(1300002, errMsg) as IFileSystemManagerFail;
};
const getSavedDir1 = ()=>{
return getEnv1().USER_DATA_PATH + '/saved';
};
let savedIndex1: [string, number] = [
'0',
0
];
const getSavedFileName1 = (filePath: string)=>{
const uriInstance = new uri.URI(filePath);
const ext = uriInstance.clearQuery().getLastSegment().split('.')[1];
let fileName = Date.now() + '';
if (savedIndex1[0] === fileName) {
savedIndex1[1]++;
if (savedIndex1[1] > 0) {
fileName += '-' + savedIndex1[1];
}
} else {
savedIndex1[0] = fileName;
savedIndex1[1] = 0;
}
if (ext) {
fileName += '.' + ext;
}
return fileName;
};
const getFsPath1 = (filePath: string)=>{
filePath = getRealPath1(filePath) as string;
if (!/^file:/.test(filePath)) {
return filePath;
}
const rawPath = filePath.replace(/^file:\/\//, '');
if (rawPath[0] === '/') {
return rawPath;
}
return filePath;
};
const DEFAULT_ENCODING = 'utf-8';
const ENCODING_SUPPORT = [
"ascii",
"base64",
"utf-8"
];
const DIGEST_ALGORITHM_VALUES = [
"md5",
"sha1"
];
const DEFAULT_POSITION = 0;
const DEFAULT_LENGTH = 0;
const DEFAULT_FLAG = 'r';
const DEFAULT_OFFSET = 0;
const FLAG = [
'a',
'ax',
'a+',
'ax+',
'as',
'as+',
'r',
'r+',
'w',
'wx',
'w+',
'wx+'
];
const useGetRealPath = (filepath: string): string =>{
return (runtimeGetRealPath(filepath) as string).replace(/^file:\/\//, '');
};
class StatsImpl implements Stats {
stat: fs3.Stat | null = null;
mode: number = -1;
size: number = -1;
lastAccessedTime: number = -1;
lastModifiedTime: number = -1;
mIsFile: boolean = false;
constructor(stat: fs3.Stat, mode: number){
this.stat = stat;
this.mode = mode;
this.size = stat.size;
this.lastAccessedTime = stat.atime;
this.lastModifiedTime = stat.mtime;
this.mIsFile = stat.isFile();
}
isDirectory(): boolean {
if (this.stat == null) {
return false;
}
return this.stat.isDirectory();
}
isFile(): boolean {
if (this.stat == null) {
return false;
}
return this.stat.isFile();
}
}
class FileSystemManagerImpl implements FileSystemManager {
readFile(options: ReadFileOptions): void {
const errMsg = `readFile: fail`;
const filePath = options.filePath, encoding = options.encoding, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const checkRes = checkPathExistence('readFile', 'filePath', filePath);
if (!checkRes.isValid) {
cb.fail({
errMsg: (checkRes as CustomValidReturn).err.errMsg
} as ApiError);
return;
}
const stat = fs3.statSync(filePath);
if (stat.isDirectory()) {
cb.fail(getApiError(1300021, errMsg));
return;
}
const lengthOfFile = stat.size;
if (encoding == undefined) {
let sizeOfNewArrayBuffer = lengthOfFile;
ohosRead(filePath, sizeOfNewArrayBuffer, cb);
} else {
const res = checkEncoding('readFile', encoding);
if (!res.isValid) {
cb.fail({
errMsg: res.errMsg
} as ApiError);
return;
}
ohosReadText(filePath, {
encoding
} as ReadTextOptions1, cb);
}
}
readFileSync(filePath: string, encoding: string | null = null): ReadFileSuccessResult {
const errMsg = `readFileSync: fail`;
const res1 = checkPathExistenceSync('readFileSync', 'filePath', filePath);
if (!res1.isValid) {
throw new Error((res1 as CustomValidReturn).err?.errMsg);
}
const stat = fs3.statSync(filePath);
if (stat.isDirectory()) {
throw new Error(getApiError(1300021, errMsg).errMsg);
}
const lengthOfFile = stat.size;
if (encoding == undefined) {
let sizeOfNewArrayBuffer = lengthOfFile;
const file = fs3.openSync(filePath, fs3.OpenMode.READ_ONLY);
const buf = new ArrayBuffer(sizeOfNewArrayBuffer);
try {
fs3.readSync(file.fd, buf);
} catch (err) {
console.error(err);
}
fs3.closeSync(file);
return {
data: buf
} as ReadFileSuccessResult;
} else {
const res2 = checkEncoding('readFileSync', encoding);
if (!res2.isValid) {
throw new Error(res2.errMsg);
}
if ((encoding as string) === 'utf8') {
encoding = 'utf-8';
}
try {
const str = fs3.readTextSync(filePath, {
encoding
} as ReadTextOptions1);
return {
data: str
} as ReadFileSuccessResult;
} catch (err) {
throw new Error(`readFileSync: ${(err as BusinessError5).message}`);
}
}
}
writeFile(options: WriteFileOptions): void {
const errMsg = `writeFile: fail`;
const filePath = options.filePath, data = options.data, _options_encoding = options.encoding, encoding = _options_encoding == null ? DEFAULT_ENCODING : _options_encoding, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(filePath, true, 'string')) {
cb.fail(getParameterError(`${errMsg} filePath`) as ApiError);
return;
}
if (!ENCODING_SUPPORT.includes(encoding)) {
cb.fail(getParameterError(`${errMsg} encoding`));
return;
}
let file: fs3.File | null = null;
try {
const stat = fs3.statSync(filePath);
if (stat.isDirectory()) {
cb.fail({
errMsg: `${errMsg} illegal operation on a directory, open: ${filePath}`
} as ApiError);
return;
}
} catch (error) {
try {
file = fs3.openSync(filePath, fs3.OpenMode.CREATE | fs3.OpenMode.WRITE_ONLY | fs3.OpenMode.TRUNC);
} catch (error) {
cb.fail(getApiError((error as BusinessError5).code, errMsg));
return;
}
}
const writeOptions: OHWriteOptions = {};
if (checkDataType((data as (string | ArrayBuffer)), true, 'string')) writeOptions.encoding = encoding as string;
if (file == null) {
file = fs3.openSync(filePath, fs3.OpenMode.WRITE_ONLY | fs3.OpenMode.TRUNC);
}
fs3.write(file.fd, data as (string | ArrayBuffer), writeOptions).then((writeLen)=>{
cb.success({
errMsg: 'writeFile: ok'
} as FileManagerSuccessResult);
}).finally(()=>{
fs3.closeSync(file);
});
}
writeFileSync(filePath: string, data: Object, encoding: string = DEFAULT_ENCODING): void {
const errMsg = `writeFileSync: fail`;
if (!checkDataType(filePath, true, 'string')) {
throw new Error(getParameterError(`${errMsg} filePath`).errMsg);
}
if (!ENCODING_SUPPORT.includes(encoding)) {
throw new Error(getParameterError(`${errMsg} encoding`).errMsg);
}
let file: fs3.File | null = null;
try {
const stat = fs3.statSync(filePath);
if (stat.isDirectory()) {
throw new Error(`${errMsg} illegal operation on a directory, open: ${filePath}`);
}
} catch (error) {
try {
file = fs3.openSync(filePath, fs3.OpenMode.CREATE | fs3.OpenMode.WRITE_ONLY | fs3.OpenMode.TRUNC);
} catch (error) {
throw new Error(getApiError((error as BusinessError5).code, errMsg).errMsg);
}
}
const writeOptions: OHWriteOptions = {};
if (checkDataType((data as (string | ArrayBuffer)), true, 'string')) writeOptions.encoding = encoding;
if (file == null) {
file = fs3.openSync(filePath, fs3.OpenMode.WRITE_ONLY | fs3.OpenMode.TRUNC);
}
try {
fs3.writeSync(file.fd, data as (string | ArrayBuffer), writeOptions);
fs3.closeSync(file);
} catch (err) {
fs3.closeSync(file);
throw new Error(`writeFileSync: ${(err as BusinessError5).message}`);
}
}
read(option: ReadOption): void {
const errMsg = 'read: fail';
let inFd = option.fd, arrayBuffer = option.arrayBuffer, offset = option.offset, length = option.length, position = option.position, success = option.success, fail = option.fail, complete = option.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
let fd: number = -1;
if (!checkDataType(inFd, true, 'string') || inFd === '' || isNaN(Number(inFd))) {
cb.fail({
errMsg: `${errMsg} invalid fd`
} as ApiError);
return;
} else {
fd = Number(inFd);
}
if (!checkDataType(arrayBuffer, true, 'arraybuffer')) {
cb.fail({
errMsg: `${errMsg} invalid arrayBuffer: ${arrayBuffer}`
} as ApiError);
return;
}
if (!checkDataType(offset, false, 'number') || offset! < 0) {
offset = Number(offset);
if (isNaN(offset) || offset < 0) {
offset = DEFAULT_OFFSET;
}
}
if (!checkDataType(length, false, 'number') || length! < 0) {
length = Number(length);
if (isNaN(length) || length < 0) {
length = DEFAULT_LENGTH;
}
}
const allowedSize = arrayBuffer.byteLength - offset!;
if (allowedSize < length!) {
cb.fail({
errMsg: `${errMsg} RangeError [ERR_OUT_OF_RANGE]: The value length is out of range. It must be <= ${allowedSize}. Received ${length}`
} as ApiError);
return;
}
if (!checkDataType(position, false, 'number') || position! < 0) {
position = DEFAULT_POSITION;
}
const offsetArrayBuffer = offset!;
const newBuffer = arrayBuffer.slice(offsetArrayBuffer);
fs3.read(fd, newBuffer, {
offset: position,
length
} as ReadOptions1).then((readLen)=>{
const viewNewBuffer = new Uint8Array(newBuffer);
const viewArrayBuffer = new Uint8Array(arrayBuffer);
viewArrayBuffer.set(viewNewBuffer, offsetArrayBuffer);
cb.success({
bytesRead: readLen,
arrayBuffer: arrayBuffer,
errMsg: 'read: ok'
} as ReadSuccessCallbackResult);
}).catch((err: BusinessError5)=>{
cb.fail({
errMsg: `${errMsg} with error message: ${err.message},error code: ${err.code}`
} as ApiError);
});
}
readSync(option: ReadSyncOption): ReadResult {
const errMsg = 'readSync: fail';
let inFd = option.fd, arrayBuffer = option.arrayBuffer, offset = option.offset, length = option.length, position = option.position;
let fd: number = -1;
if (!checkDataType(inFd, true, 'string') || inFd === '' || isNaN(Number(inFd))) {
throw new Error(`${errMsg} invalid fd`);
} else {
fd = Number(inFd);
}
if (!checkDataType(arrayBuffer, true, 'arraybuffer')) {
throw new Error(`${errMsg} invalid arrayBuffer`);
}
if (!checkDataType(offset, false, 'number') || offset! < 0) {
offset = Number(offset);
if (isNaN(offset) || offset < 0) {
offset = DEFAULT_OFFSET;
}
}
if (!checkDataType(length, false, 'number') || length! < 0) {
length = Number(length);
if (isNaN(length) || length < 0) {
length = DEFAULT_LENGTH;
}
}
const allowedSize = arrayBuffer.byteLength - offset!;
if (allowedSize < length!) {
throw new Error(`${errMsg} RangeError [ERR_OUT_OF_RANGE]: The value length is out of range. It must be <= ${allowedSize}. Received ${length}`);
}
if (!checkDataType(position, false, 'number') || position! < 0) {
position = DEFAULT_POSITION;
}
try {
const offsetArrayBuffer = offset!;
let newBuffer = arrayBuffer.slice(offsetArrayBuffer);
const len = fs3.readSync(fd, newBuffer, {
offset: position,
length
} as ReadOptions1);
const viewNewBuffer = new Uint8Array(newBuffer);
let viewArrayBuffer = new Uint8Array(arrayBuffer);
viewArrayBuffer.set(viewNewBuffer, offsetArrayBuffer);
return {
bytesRead: len,
arrayBuffer: arrayBuffer
} as ReadResult;
} catch (err) {
throw new Error(`${errMsg} ${(err as BusinessError5).message}`);
}
}
unlink(options: UnLinkOptions): void {
const errMsg = 'unlink: fail';
const filePath = options.filePath, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const res = checkPathExistence('unlink', 'filePath', filePath);
if (!res.isValid) {
cb.fail((res as CustomValidReturn).err);
return;
}
const stat = fs3.statSync(filePath);
if (stat.isDirectory()) {
cb.fail({
errMsg: `${errMsg} illegal operation on a directory, unlink: ${filePath}`
} as ApiError);
return;
}
fs3.unlink(filePath).then(()=>{
cb.success({
errMsg: 'unlink: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail({
errMsg: `${errMsg} with error message: ${err.message}, error code: ${err.code}`
} as ApiError);
});
}
unlinkSync(filePath: string): void {
const errMsg = 'unlinkSync: fail';
const res = checkPathExistenceSync('unlinkSync', 'filePath', filePath);
if (!res.isValid) {
throw new Error((res as CustomValidReturn).err?.errMsg);
}
if (fs3.statSync(filePath).isDirectory()) {
throw new Error(`${errMsg} illegal operation on a directory, unlink: ${filePath}`);
}
try {
fs3.unlinkSync(filePath);
} catch (err) {
throw new Error(`${errMsg} ${(err as BusinessError5).message}`);
}
}
mkdir(options: MkDirOptions): void {
const errMsg = `mkdir: fail`;
let dirPath = options.dirPath, recursive = options.recursive, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
const checkRes = checkPath('mkdir', 'dirPath', dirPath);
if (!checkRes.isValid) {
cb.fail((checkRes as CustomValidReturn).err);
return;
}
if (fs3.accessSync(dirPath)) {
cb.fail({
errMsg: `${errMsg} dirPath already exists: ${dirPath}`
} as ApiError);
return;
}
const getSubPath = obtainUpperPath(dirPath);
if (!recursive && !fs3.accessSync(getSubPath.upperPath)) {
cb.fail({
errMsg: `${errMsg} recursive is false and upper path does not exist`
} as ApiError);
return;
}
fs3.mkdir(dirPath, recursive).then(()=>{
cb.success({
errMsg: 'mkdir: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError(err.code, errMsg));
});
}
mkdirSync(dirPath: string, recursive: boolean): void {
const errMsg = `mkdirSync: fail`;
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
const res = checkPathSync('mkdirSync', 'dirPath', dirPath);
if (!res.isValid) {
throw new Error((res as CustomValidReturn).err?.errMsg);
}
if (fs3.accessSync(dirPath)) {
throw new Error(`${errMsg} dirPath already exists: ${dirPath}`);
}
if (!recursive && !fs3.accessSync(obtainUpperPath(dirPath).upperPath)) {
throw new Error(`${errMsg} recursive is false and upper path does not exist`);
}
try {
fs3.mkdirSync(dirPath, recursive);
} catch (error) {
throw new Error(getApiError((error as BusinessError5).code, errMsg).errMsg);
}
}
rmdir(options: RmDirOptions): void {
const errMsg = 'rmdir: fail';
let dirPath = options.dirPath, recursive = options.recursive, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
const res = checkPathExistence('rmdir', 'dirPath', dirPath);
if (!res.isValid) {
cb.fail((res as CustomValidReturn).err);
return;
}
if (!fs3.statSync(dirPath).isDirectory()) {
cb.fail({
errMsg: `${errMsg} no such directory, open: ${dirPath}`
} as ApiError);
return;
}
if (!recursive) {
let filenames = fs3.listFileSync(dirPath);
if (filenames.length) {
cb.fail({
errMsg: `${errMsg} directory not empty`
} as ApiError);
return;
}
}
fs3.rmdir(dirPath).then(()=>{
cb.success({
errMsg: 'rmdir: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
rmdirSync(dirPath: string, recursive: boolean): void {
const errMsg = 'rmdirSync: fail';
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
const res = checkPathExistenceSync('rmdirSync', 'dirPath', dirPath);
if (!res.isValid) {
throw new Error((res as CustomValidReturn).err?.errMsg);
}
if (!fs3.statSync(dirPath).isDirectory()) {
throw new Error(`${errMsg} no such directory, open: ${dirPath}`);
}
if (!recursive && (fs3.listFileSync(dirPath).length > 0)) {
throw new Error(`${errMsg} directory not empty`);
}
try {
fs3.rmdirSync(dirPath);
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
readdir(options: ReadDirOptions): void {
const errMsg = 'readdir: fail';
const dirPath = options.dirPath, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const checkRes = checkPathExistence('readdir', 'dirPath', dirPath);
if (!checkRes.isValid) {
cb.fail((checkRes as CustomValidReturn).err);
return;
}
const stat = fs3.statSync(dirPath);
if (stat.isFile()) {
cb.fail({
errMsg: `${errMsg} dirPath not a directory: ${dirPath}`
} as ApiError);
return;
}
fs3.listFile(dirPath).then((files)=>{
cb.success({
files,
errMsg: 'readdir: ok'
} as ReadDirSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail({
errMsg: `${errMsg} with error message: ${err.message}, error code: ${err.code}`
} as ApiError);
});
}
readdirSync(dirPath: string): string[] | null {
const errMsg = 'readdirSync: fail';
const res = checkPathExistenceSync('readdirSync', 'dirPath', dirPath);
if (!res.isValid) {
throw new Error((res as CustomValidReturn).err?.errMsg);
}
if (fs3.statSync(dirPath).isFile()) {
throw new Error(`${errMsg} not a directory: ${dirPath}`);
}
try {
return fs3.listFileSync(dirPath);
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
access(options: AccessOptions): void {
const errMsg = 'access: fail';
const path = options.path, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(path, true, 'string')) {
cb.fail(getParameterError(`${errMsg} path`));
return;
}
fs3.access(path).then((res)=>{
if (res) {
cb.success({
errMsg: 'access: ok'
} as FileManagerSuccessResult);
} else {
cb.fail(getNoSuchFileOrDirectoryError(errMsg));
}
}, (err: BusinessError5)=>{
cb.fail({
errCode: err.code,
errMsg: getApiError(err.code, errMsg).errMsg
} as ApiError);
});
}
accessSync(path: string): void {
const errMsg = 'accessSync: fail';
if (!checkDataType(path, true, 'string')) {
throw new Error(`${errMsg} path must be a string`);
}
const res = fs3.accessSync(path);
if (!res) {
throw new Error(`${errMsg} no such file or directory`);
}
}
rename(options: RenameOptions): void {
const errMsg = 'rename: fail';
const oldPath = options.oldPath, newPath = options.newPath, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const checkRes1 = checkPathExistence('rename', 'oldPath', oldPath);
if (!checkRes1.isValid) {
cb.fail((checkRes1 as CustomValidReturn).err);
return;
}
const checkRes2 = checkPath('rename', 'newPath', newPath);
if (!checkRes2.isValid) {
cb.fail((checkRes2 as CustomValidReturn).err);
return;
}
const ifAccessNewPath = fs3.accessSync(newPath);
if (!ifAccessNewPath) {
const getUpperPath = obtainUpperPath(newPath);
if (!fs3.accessSync(getUpperPath.upperPath)) {
cb.fail({
errMsg: `${errMsg} no such file or directory: ${newPath}`
} as ApiError);
return;
}
}
if (ifAccessNewPath && (oldPath !== newPath)) {
cb.fail({
errMsg
} as ApiError);
return;
}
fs3.rename(oldPath, newPath).then(()=>{
cb.success({
errMsg: 'rename: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail({
errMsg: getApiError((err as BusinessError5).code, errMsg).errMsg
} as ApiError);
});
}
renameSync(oldPath: string, newPath: string): void {
const errMsg = 'renameSync: fail';
const res1 = checkPathExistenceSync('renameSync', 'oldPath', oldPath);
if (!res1.isValid) {
throw new Error((res1 as CustomValidReturn).err?.errMsg);
}
const res2 = checkPathSync('renameSync', 'newPath', newPath);
if (!res2.isValid) {
throw new Error((res2 as CustomValidReturn).err?.errMsg);
}
const ifAccessNewPath = fs3.accessSync(newPath);
if (!ifAccessNewPath && !fs3.accessSync(obtainUpperPath(newPath).upperPath)) {
throw new Error(`${errMsg} no such file or directory, open: ${newPath}`);
}
if (ifAccessNewPath && (oldPath !== newPath)) {
throw new Error(errMsg);
}
try {
fs3.renameSync(oldPath, newPath);
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
copyFile(options: CopyFileOptions): void {
const errMsg = 'copyFile: fail';
let srcPath = options.srcPath, destPath = options.destPath, success = options.success, fail = options.fail, complete = options.complete;
srcPath = useGetRealPath(srcPath);
destPath = useGetRealPath(destPath);
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const checkResOfSrcPath = checkPathExistence('copyFile', 'srcPath', srcPath);
if (!checkResOfSrcPath.isValid) {
cb.fail((checkResOfSrcPath as CustomValidReturn).err);
return;
}
const checkResOfDestPath = checkPath('copyFile', 'destPath', destPath);
if (!checkResOfDestPath.isValid) {
cb.fail((checkResOfDestPath as CustomValidReturn).err);
return;
}
if (fs3.statSync(srcPath).isDirectory()) {
cb.fail({
errMsg: `${errMsg} illegal operation on a directory, open: ${srcPath}`
} as ApiError);
return;
}
if (!fs3.accessSync(destPath)) {
const getUpperPath = obtainUpperPath(destPath);
if (!fs3.accessSync(getUpperPath.upperPath)) {
cb.fail({
errMsg: `${errMsg} no such file or directory, open: ${destPath}`
} as ApiError);
return;
}
} else {
const destPathStat = fs3.statSync(destPath);
if (destPathStat.isDirectory()) {
destPath = destPath + obtainFileName(srcPath).fileName;
} else {
if (destPathStat.isFile() && (srcPath !== destPath)) {
cb.fail({
errMsg
} as ApiError);
return;
}
}
}
fs3.copyFile(srcPath, destPath).then(()=>{
cb.success({
errMsg: 'copyFile: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
copyFileSync(srcPath: string, destPath: string): void {
const errMsg = 'copyFileSync: fail';
srcPath = useGetRealPath(srcPath);
destPath = useGetRealPath(destPath);
const checkResSrc = checkPathExistenceSync('copyFileSync', 'srcPath', srcPath);
if (!checkResSrc.isValid) {
throw new Error((checkResSrc as CustomValidReturn).err?.errMsg);
}
const checkResDest = checkPathSync('copyFileSync', 'destPath', destPath);
if (!checkResDest.isValid) {
throw new Error((checkResDest as CustomValidReturn).err?.errMsg);
}
if (fs3.statSync(srcPath).isDirectory()) {
throw new Error(`${errMsg} illegal operation on a directory: ${srcPath}`);
}
if (!fs3.accessSync(destPath)) {
const getUpperPath = obtainUpperPath(destPath);
if (!fs3.accessSync(getUpperPath.upperPath)) {
throw new Error(`${errMsg} no such file or directory: ${destPath}`);
}
} else {
const destPathStat = fs3.statSync(destPath);
if (destPathStat.isDirectory()) {
const index = destPath.lastIndexOf('/');
let namePath = destPath.substring(index);
if (destPath.endsWith('/')) {
namePath = destPath.substring(destPath.lastIndexOf('/', destPath.length - 2) + 1, destPath.length - 1);
}
destPath = destPath + namePath;
} else {
if (destPathStat.isFile() && (srcPath !== destPath)) {
throw new Error(`${errMsg} copyFile failed`);
}
}
}
try {
fs3.copyFileSync(srcPath, destPath);
} catch (err) {
throw new Error(`copyFileSync: ${(err as BusinessError5).message}`);
}
}
getFileInfo(options: GetFileInfoOptions): void {
const errMsg = 'getFileInfo: fail';
let filePath = options.filePath, success = options.success, fail = options.fail, complete = options.complete;
let digestAlgorithm: string = options.digestAlgorithm ?? 'md5';
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const checkResOfFilePath = checkPathExistence('getFileInfo', 'filePath', filePath);
if (!checkResOfFilePath.isValid) {
cb.fail((checkResOfFilePath as CustomValidReturn).err);
return;
}
if (typeof digestAlgorithm === 'string') {
digestAlgorithm = digestAlgorithm.toUpperCase();
}
if (!DIGEST_ALGORITHM_VALUES.includes(digestAlgorithm)) {
digestAlgorithm = 'md5';
}
try {
const fd = fs3.openSync(filePath, fs3.OpenMode.READ_WRITE).fd;
const stat = isFileUri1(filePath) ? fs3.statSync(fd) : fs3.statSync(filePath);
const buf = new ArrayBuffer(stat.size);
fs3.readSync(fd, buf);
const algName = digestAlgorithm.toLocaleUpperCase();
SecurityBase.rsa(algName, {
data: new Uint8Array(buf)
} as cryptoFramework1.DataBlob).then((resultBuf: Uint8Array)=>{
const textDecoder = util1.TextDecoder.create('utf-8', {
ignoreBOM: true
} as util1.TextDecoderOptions);
cb.success({
errMsg: 'getFileInfo ok',
size: stat.size,
digest: textDecoder.decodeToString(resultBuf, {
stream: false
} as util1.DecodeToStringOptions)
} as GetFileInfoSuccessResult);
});
} catch (err) {
cb.fail(getApiError((err as BusinessError5).code, errMsg));
}
}
stat(options: StatOptions): void {
const errMsg = 'stat: fail';
let path = options.path, recursive = options.recursive, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const res = checkPathExistence('stat', 'path', path);
if (!res.isValid) {
cb.fail((res as CustomValidReturn).err);
return;
}
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
fs3.stat(path, (err, stat)=>{
if (err) {
cb.fail({
errMsg: `${errMsg} with error message: ${err.message}, error code: ${err.code}`
} as ApiError);
} else {
const combinationMode = getFileTypeMode(stat) | stat.mode;
const fileStats = {
path,
stats: new StatsImpl(stat, combinationMode)
} as FileStats;
cb.success({
stats: [
fileStats
] as FileStats[],
errMsg: 'stat: ok'
} as StatSuccessResult);
}
});
}
statSync(path: string, recursive: boolean): FileStats[] {
const errMsg = 'statSync: fail';
const res = checkPathExistenceSync('statSync', 'path', path);
if (!res.isValid) {
throw new Error((res as CustomValidReturn).err?.errMsg);
}
if (!checkDataType(recursive, false, 'boolean')) {
recursive = Boolean(recursive);
}
try {
const stat = fs3.statSync(path);
const combinationMode = getFileTypeMode(stat) | stat.mode;
const fileStats = {
path,
stats: new StatsImpl(stat, combinationMode)
} as FileStats;
return [
fileStats
] as FileStats[];
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
appendFile(options: AppendFileOptions): void {
const errMsg = 'appendFile: fail';
const filePath = options.filePath, data = options.data, _options_encoding = options.encoding, encoding = _options_encoding == null ? DEFAULT_ENCODING : _options_encoding, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(filePath, true, 'string')) {
cb.fail(getParameterError(`${errMsg} filePath`));
return;
}
if (!checkDataType(data, true, 'string') && !checkDataType(data, true, 'arraybuffer')) {
cb.fail(getParameterError(`${errMsg} data`));
return;
}
const res = fs3.accessSync(filePath);
if (!res) {
cb.fail(getNoSuchFileOrDirectoryError(errMsg));
return;
}
const writeOptions: OHWriteOptions = {};
if (checkDataType(data, true, 'string')) writeOptions.encoding = encoding;
const file = fs3.openSync(filePath, fs3.OpenMode.READ_WRITE | fs3.OpenMode.APPEND);
fs3.write(file.fd, data as (string | ArrayBuffer), writeOptions).then((_)=>{
cb.success({
errMsg: 'appendFile:ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError(err.code, errMsg));
}).finally(()=>{
fs3.closeSync(file);
});
}
appendFileSync(filePath: string, data: Object, encoding: string = DEFAULT_ENCODING): void {
const errMsg = 'appendFileSync: fail';
if (!checkDataType(filePath, true, 'string')) {
throw new Error(`${errMsg} parameter error: parameter.filePath should be String`);
}
if (!checkDataType(data, true, 'string') && !checkDataType(data, true, 'arraybuffer')) {
throw new Error(`${errMsg} parameter error: parameter.data should be String/ArrayBuffer`);
}
const res = fs3.accessSync(filePath);
if (!res) {
throw new Error(`${errMsg} no such file or directory, open "${filePath}"`);
}
const writeOptions: OHWriteOptions = {};
if (checkDataType(data, true, 'string')) writeOptions.encoding = encoding;
const file = fs3.openSync(filePath, fs3.OpenMode.READ_WRITE | fs3.OpenMode.APPEND);
fs3.writeSync(file.fd, data as (string | ArrayBuffer), writeOptions);
}
saveFile(options: SaveFileOptions): void {
const errMsg = 'saveFile: fail';
const filePath = options.filePath, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const tempFilePath = useGetRealPath(options.tempFilePath) as string;
if (!fs3.accessSync(tempFilePath)) {
cb.fail({
errMsg: `${errMsg} no such file or directory. tempFilePath: ${tempFilePath}`
} as ApiError);
return;
}
const savedPath = filePath || getSavedDir1();
try {
if (!fs3.accessSync(savedPath)) {
fs3.mkdirSync(savedPath, true);
}
} catch (error) {
cb.fail({
errMsg: (error as Error).message
} as ApiError);
return;
}
let srcFile: fs3.File;
try {
srcFile = fs3.openSync(tempFilePath, fs3.OpenMode.READ_ONLY);
} catch (error) {
cb.fail({
errMsg: (error as Error).message
} as ApiError);
return;
}
const savedFilePath = savedPath + '/' + getSavedFileName1(tempFilePath);
fs3.copyFile(srcFile.fd, savedFilePath).then(()=>{
cb.success({
savedFilePath
} as SaveFileSuccessResult);
}).catch((err: Error)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
saveFileSync(inTempFilePath: string, filePath: string | null): string {
const errMsg = 'saveFileSync: fail';
const tempFilePath = useGetRealPath(inTempFilePath) as string;
if (!fs3.accessSync(tempFilePath)) {
throw new Error(`${errMsg} no such file or directory. tempFilePath: ${tempFilePath}`);
}
const savedPath = filePath || getSavedDir1();
try {
if (!fs3.accessSync(savedPath)) {
fs3.mkdirSync(savedPath, true);
}
} catch (error) {
throw new Error((error as Error).message);
}
let srcFile: fs3.File;
try {
srcFile = fs3.openSync(tempFilePath, fs3.OpenMode.READ_ONLY);
} catch (error) {
throw new Error((error as Error).message);
}
const savedFilePath = `${savedPath}${savedPath.endsWith('/') ? '' : '/'}${getSavedFileName1(tempFilePath)}`;
try {
fs3.copyFileSync(srcFile.fd, savedFilePath);
return savedFilePath;
} catch (error) {
throw new Error((error as Error).message);
}
}
removeSavedFile(options: RemoveSavedFileOptions): void {
const filePath = options.filePath, success = options.success, fail = options.fail, complete = options.complete;
const savedFilePath = getFsPath1(filePath);
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!fs3.accessSync(savedFilePath)) {
cb.fail({
errMsg: 'file not exist'
} as ApiError);
return;
}
fs3.unlink(savedFilePath, (err)=>{
if (err) {
cb.fail(getApiError(err.code, 'removeSavedFile: fail'));
} else {
cb.success({
errMsg: 'removeSavedFile: ok'
} as FileManagerSuccessResult);
}
});
}
getSavedFileList(options: GetSavedFileListOptions): void {
const errMsg = 'getSavedFileList: fail';
const success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const savedPath = getSavedDir1();
if (!fs3.accessSync(savedPath)) {
cb.fail(getApiError(1300002, errMsg));
return;
}
fs3.listFile(savedPath, {} as ListFileOptions1, (err, fileList)=>{
if (err) {
cb.fail(getApiError(err.code, errMsg));
} else {
cb.success({
fileList: fileList.map((filePath: string)=>{
const fullPath = savedPath + '/' + filePath;
const stat = fs3.statSync(fullPath);
if (!stat.isFile()) {
return null;
}
return fullPath;
}).filter((item)=>!!item)
} as GetSavedFileListResult);
}
});
}
truncate(options: TruncateFileOptions): void {
const errMsg = 'truncate: fail';
let filePath = options.filePath, length = options.length, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(filePath, true, 'string')) {
cb.fail({
errMsg: `${errMsg} parameter error: parameter.filePath should be String`
} as ApiError);
return;
}
const res = fs3.accessSync(filePath);
if (!res) {
cb.fail({
errMsg: `${errMsg} no such file or directory, open "${filePath}"`
} as ApiError);
return;
}
const fileStat = fs3.statSync(filePath);
if (fileStat.isDirectory()) {
cb.fail({
errMsg: `${errMsg} illegal operation on a directory, open: ${filePath}`
} as ApiError);
return;
}
if (!checkDataType(length, false, 'number') || length! < 0) {
length = 0;
}
const file = fs3.openSync(filePath, fs3.OpenMode.READ_WRITE);
fs3.truncate(file.fd, length).then(()=>{
cb.success({
errMsg: 'truncate: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError(err.code, errMsg));
});
}
truncateSync(filePath: string, length: number | null = null): void {
const errMsg = 'truncateSync: fail';
if (!checkDataType(filePath, true, 'string')) {
throw new Error(`${errMsg} parameter error: parameter.filePath should be String`);
}
const res = fs3.accessSync(filePath);
if (!res) {
throw new Error(`${errMsg} no such file or directory, open "${filePath}"`);
}
const fileStat = fs3.statSync(filePath);
if (fileStat.isDirectory()) {
throw new Error(`${errMsg} illegal operation on a directory, open: ${filePath}`);
}
if (!checkDataType(length, false, 'number') || length! < 0) {
length = 0;
}
const file = fs3.openSync(filePath, fs3.OpenMode.READ_WRITE);
try {
fs3.truncateSync(file.fd, length!);
} catch (error) {
throw new Error(getApiError((error as BusinessError5).code, errMsg).errMsg);
}
}
open(options: OpenFileOptions): void {
const errMsg = 'open: fail';
let filePath = options.filePath, flag = options.flag, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(filePath, true, 'string')) {
cb.fail({
errMsg: `${errMsg} parameter error: parameter.filePath should be String`
} as ApiError);
return;
}
if (!FLAG.includes(flag)) {
flag = DEFAULT_FLAG;
}
if (Object.keys(modeReflect).includes(flag)) {
if (fs3.accessSync(filePath)) {
cb.fail({
errMsg: `${errMsg} EXIST: file already exists`
} as ApiError);
return;
} else {
flag = modeReflect[flag as keyof ModeReflect] as _FLAG;
}
}
fs3.open(filePath, getOpenMode(flag)!, (err, file)=>{
if (err) {
cb.fail(getApiError(err.code, errMsg));
} else {
cb.success({
fd: file.fd.toString(),
errMsg: 'open: ok'
} as OpenFileSuccessResult);
}
});
}
openSync(options: OpenFileSyncOptions): string {
let filePath = options.filePath, flag = options.flag;
if (!checkDataType(filePath, true, 'string')) {
throw new Error('openSync:fail parameter error: parameter.filePath should be String');
}
if (!FLAG.includes(flag)) {
flag = DEFAULT_FLAG;
}
if (Object.keys(modeReflect).includes(flag)) {
if (fs3.accessSync(filePath)) {
throw new Error('openSync:fail EXIST: file already exists');
} else {
flag = modeReflect[flag as keyof ModeReflect] as _FLAG;
}
}
const file = fs3.openSync(filePath, getOpenMode(flag)!);
return file.fd.toString();
}
write(options: WriteOptions): void {
let inFd = options.fd, data = options.data, offset = options.offset, length = options.length, position = options.position, _options_encoding = options.encoding, encoding = _options_encoding == null ? 'utf-8' : _options_encoding, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
let fd: number = -1;
const writeOptions: OHWriteOptions = {};
if (!checkDataType(inFd, true, 'string') || inFd === '' || isNaN(Number(inFd))) {
cb.fail({
errMsg: 'write: fail invalid fd'
} as ApiError);
return;
} else {
fd = Number(inFd);
}
if (!checkDataType((data as DataType), true, 'arraybuffer') && !checkDataType((data as DataType), true, 'string')) {
cb.fail({
errMsg: 'write: fail data must be a string or ArrayBuffer'
} as ApiError);
return;
}
if (checkDataType((data as DataType), true, 'arraybuffer')) {
const sizeOfArrayBuffer = (data as ArrayBuffer).byteLength as number;
if (!checkDataType(offset, false, 'number') || offset! < 0 || !offset) {
offset = DEFAULT_OFFSET;
}
if (offset > sizeOfArrayBuffer) {
cb.fail({
errMsg: `write: fail RangeError [ERR_OUT_OF_RANGE]: The value of offset is out of range. It must be <= ${sizeOfArrayBuffer}. Received ${offset}`
} as ApiError);
return;
}
if (!checkDataType(length, false, 'number') || length! < 0 || !length) {
length = sizeOfArrayBuffer - offset;
}
if (length > sizeOfArrayBuffer - offset) {
cb.fail({
errMsg: `write: fail RangeError [ERR_OUT_OF_RANGE]: The value of length is out of range. It must be <= ${sizeOfArrayBuffer - offset}. Received ${length}`
} as ApiError);
return;
}
const uint8ArrayTemp = new Uint8Array(data as ArrayBuffer);
const slicedArray = uint8ArrayTemp.slice(offset);
data = slicedArray.buffer;
}
if (checkDataType((data as DataType), true, 'string')) {
const res = checkEncoding('write', encoding);
if (!res.isValid) {
cb.fail({
errMsg: res.errMsg
} as ApiError);
return;
}
writeOptions.encoding = encoding as string;
length = buffer.byteLength(data as string);
}
if (!checkDataType(position, false, 'number') || position! < 0 || !position) {
position = DEFAULT_POSITION;
}
writeOptions.offset = position;
writeOptions.length = length!;
fs3.write(fd, data as (ArrayBuffer | string), writeOptions).then((writeLen)=>{
cb.success({
bytesWritten: writeLen,
errMsg: 'write:ok'
} as WriteResult);
}).catch((err: BusinessError5)=>{
cb.fail({
errMsg: `write data to file failed with error message: ${err.message}, error code: ${err.code}`
} as ApiError);
});
}
writeSync(options: WriteSyncOptions): WriteResult {
let inFd = options.fd, data = options.data, offset = options.offset, length = options.length, position = options.position, _options_encoding = options.encoding, encoding = _options_encoding == null ? 'utf-8' : _options_encoding;
let fd: number = -1;
const writeOptions: OHWriteOptions = {};
if (!checkDataType(inFd, true, 'string') || inFd === '' || isNaN(Number(inFd))) {
throw new Error('writeSync: fail invalid fd');
} else {
fd = Number(inFd);
}
if (!checkDataType((data as DataType), true, 'arraybuffer') && !checkDataType((data as DataType), true, 'string')) {
throw new Error('writeSync: fail data must be a string or ArrayBuffer');
}
if (checkDataType((data as DataType), true, 'arraybuffer')) {
const sizeOfArrayBuffer = (data as ArrayBuffer).byteLength as number;
if (!checkDataType(offset, false, 'number') || offset! < 0 || !offset) {
offset = DEFAULT_OFFSET;
}
if (offset > sizeOfArrayBuffer) {
throw new Error(`write: fail RangeError [ERR_OUT_OF_RANGE]: The value of offset is out of range. It must be <= ${sizeOfArrayBuffer}. Received ${offset}`);
}
if (!checkDataType(length, false, 'number') || length! < 0 || !length) {
length = sizeOfArrayBuffer - offset;
}
if (length > sizeOfArrayBuffer - offset) {
throw new Error(`write: fail RangeError [ERR_OUT_OF_RANGE]: The value of length is out of range. It must be <= ${sizeOfArrayBuffer - offset}. Received ${length}`);
}
const uint8ArrayTemp = new Uint8Array(data as ArrayBuffer);
const slicedArray = uint8ArrayTemp.slice(offset);
data = slicedArray.buffer;
}
if (checkDataType((data as DataType), true, 'string')) {
const res = checkEncoding('write', encoding);
if (!res.isValid) {
throw new Error(res.errMsg);
}
writeOptions.encoding = encoding as string;
length = buffer.byteLength(data as string);
}
if (!checkDataType(position, false, 'number') || position! < 0 || !position) {
position = DEFAULT_POSITION;
}
writeOptions.offset = position;
writeOptions.length = length!;
try {
const writeLen = fs3.writeSync(fd, data as (ArrayBuffer | string), writeOptions);
return {
bytesWritten: writeLen,
errMsg: 'write:ok'
} as WriteResult;
} catch (error) {
throw new Error(`writeSync: fail ${(error as BusinessError5).message}`);
}
}
close(options: CloseOptions): void {
const errMsg = 'close: fail';
let inFd = options.fd, success = options.success, fail = options.fail, complete = options.complete;
let fd: number = -1;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const res = checkFd('fstat', inFd);
if (!res.isValid) {
cb.fail((res as CheckFdErr).err);
return;
}
fd = res.fd;
if (isNaN(fd)) {
cb.fail({
errMsg: `${errMsg} bad file descriptor`
} as ApiError);
return;
}
fs3.close(fd, (err)=>{
if (err) {
cb.fail({
errMsg: `${errMsg} bad file descriptor`
} as ApiError);
} else {
cb.success({
errMsg: 'close:ok'
} as FileManagerSuccessResult);
}
});
}
closeSync(options: CloseSyncOptions): void {
const errMsg = 'closeSync: fail';
let inFd = options.fd;
let fd: number = -1;
if (inFd === '' || !checkDataType(inFd, true, 'string')) {
throw new Error(`${errMsg} invalid fd`);
}
fd = Number(inFd);
if (isNaN(fd)) {
throw new Error(`${errMsg} bad file descriptor`);
}
fs3.closeSync(fd);
}
fstat(options: FStatOptions): void {
const errMsg = 'fstat: fail';
let inFd = options.fd, success = options.success, fail = options.fail, complete = options.complete;
let fd: number = -1;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
const res = checkFd('fstat', inFd);
if (!res.isValid) {
cb.fail((res as CheckFdErr).err);
return;
} else {
fd = res.fd;
}
fs3.stat(fd, (err, stat)=>{
if (err) {
cb.fail(getApiError(err.code, errMsg));
} else {
const combinationMode = getFileTypeMode(stat) | stat.mode;
cb.success({
stats: new StatsImpl(stat, combinationMode)
} as FStatSuccessResult);
}
});
}
fstatSync(options: FStatSyncOptions): Stats {
const errMsg = 'fstatSync: fail';
let fd: number = -1;
const res = checkFd('fstatSync', options.fd);
if (!res.isValid) {
throw new Error((res as CheckFdErr).err?.errMsg);
} else {
fd = res.fd;
}
try {
const stat = fs3.statSync(fd);
const combinationMode = getFileTypeMode(stat) | stat.mode;
return new StatsImpl(stat, combinationMode);
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
ftruncate(options: FTruncateFileOptions): void {
const errMsg = 'ftruncate: fail';
let inFd = options.fd, length = options.length, success = options.success, fail = options.fail, complete = options.complete;
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
let fd: number = -1;
const res = checkFd('ftruncate', inFd);
if (!res.isValid) {
cb.fail((res as CheckFdErr).err);
return;
} else {
fd = res.fd;
}
if (!checkDataType(length, true, 'number') || length < 0) {
length = DEFAULT_LENGTH;
}
fs3.truncate(fd, length).then(()=>{
cb.success({
errMsg: 'ftruncate: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
ftruncateSync(options: FTruncateFileSyncOptions): void {
const errMsg = 'ftruncateSync: fail';
let inFd = options.fd, length = options.length;
const res = checkFd('ftruncateSync', inFd);
let fd: number = -1;
if (!res.isValid) {
throw new Error((res as CheckFdErr).err?.errMsg);
} else {
fd = res.fd;
}
if (!checkDataType(length, true, 'number') || length < 0) {
length = DEFAULT_LENGTH;
}
try {
fs3.truncateSync(fd, length);
} catch (err) {
throw new Error(getApiError((err as BusinessError5).code, errMsg).errMsg);
}
}
unzip(options: UnzipFileOptions): void {
const errMsg = 'unzip: fail';
let zipFilePath = options.zipFilePath, targetPath = options.targetPath, success = options.success, fail = options.fail, complete = options.complete;
zipFilePath = useGetRealPath(zipFilePath);
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
if (!checkDataType(zipFilePath, true, 'string')) {
cb.fail(getParameterError(`${errMsg} zipFilePath`));
return;
}
if (!checkDataType(targetPath, true, 'string')) {
cb.fail(getParameterError(`${errMsg} targetPath`));
return;
}
const res = fs3.accessSync(zipFilePath);
if (!res) {
cb.fail(getNoSuchFileOrDirectoryError(errMsg));
return;
}
const targetStat = fs3.statSync(targetPath);
if (!targetStat.isDirectory()) {
cb.fail(getApiError(1300016, errMsg));
return;
}
zlib.decompressFile(zipFilePath, targetPath).then(()=>{
cb.success({
errMsg: 'unzip: ok'
} as FileManagerSuccessResult);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
readZipEntry(options: ReadZipEntryOptions): void {
const errMsg = 'readZipEntry: fail';
const okMsg = 'readZipEntry: ok';
let filePath = options.filePath, encoding = options.encoding, entries = options.entries, success = options.success, fail = options.fail, complete = options.complete;
filePath = useGetRealPath(filePath);
const cb = new FileCallback({
success,
fail,
complete
} as CallBack);
let isAll = false;
let encodeArrayBuffer = false;
if (!checkDataType(filePath, true, 'string')) {
cb.fail(getParameterError(`${errMsg} filePath`));
return;
}
if (entries != null) {
if (!Array.isArray(entries)) {
cb.fail(getParameterError(`${errMsg} entries`));
return;
} else {
if (entries.length === 0) {
cb.fail(getParameterError(`${errMsg} entries`));
return;
}
}
} else {
isAll = true;
if (encoding == null) {
encodeArrayBuffer = true;
} else if (isString(encoding)) {
if ((encoding as string) === 'utf8') {
encoding = 'utf-8';
}
}
}
if (isString(encoding) && !ENCODING_SUPPORT.includes(encoding as string)) {
cb.fail(getParameterError(`${errMsg} encoding`));
return;
}
const res = fs3.accessSync(filePath);
if (!res) {
cb.fail(getNoSuchFileOrDirectoryError(errMsg));
return;
}
const targetPath = `${getEnv2().TEMP_PATH}/unzip/${Date.now().toString()}`;
fs3.mkdir(targetPath, true).then(()=>{
this.unzip({
zipFilePath: filePath,
targetPath,
success: ()=>{
const entriesResult: Map<string, ZipFileItem> = new Map();
const readFileSync = (file: string, fullPath: string, encoding: string | null = null)=>{
const data = this.readFileSync(fullPath).data as ArrayBuffer;
if (encodeArrayBuffer) {
entriesResult.set(file, {
data,
errMsg: okMsg
} as ZipFileItem);
} else {
entriesResult.set(file, {
data: buffer.from(data).toString(encoding as string),
errMsg: okMsg
} as ZipFileItem);
}
};
try {
if (isAll) {
const files = fs3.listFileSync(targetPath);
for (const file of files){
const fullPath = `${targetPath}/${file}`;
if (fs3.statSync(fullPath).isFile()) {
readFileSync(file, fullPath, encoding as string);
}
}
} else {
for (const entry of entries!){
const entryPath = entry.path;
const fullPath = `${targetPath}/${entryPath}`;
if (!fs3.accessSync(fullPath) || !fs3.statSync(fullPath).isFile()) {
continue;
}
readFileSync(entryPath, fullPath, entry.encoding as string);
}
}
cb.success({
entries: entriesResult,
result: entriesResult,
errMsg: okMsg
} as EntriesResult);
} catch (err) {
cb.fail({
errMsg: `${errMsg} ${(err as Error).message}`
} as FileManagerSuccessResult);
}
},
fail: cb.fail,
complete: null
} as UnzipFileOptions);
}).catch((err: BusinessError5)=>{
cb.fail(getApiError((err as BusinessError5).code, errMsg));
});
}
readCompressedFile(options: ReadCompressedFileOptions): void {
throw new Error('Method not implemented.');
}
readCompressedFileSync(filePath: string, compressionAlgorithm: string): string {
throw new Error('Method not implemented.');
}
}
const getFileSystemManager = defineSyncApi<FileSystemManager>(GET_FILE_SYSTEM_MANAGER, ()=>{
return new FileSystemManagerImpl();
});
const AUTHORIZED = 'authorized';
const DENIED = 'denied';
const NOT_DETERMINED = 'not determined';
class AppAuthorizeSetting {
albumAuthorized: string = NOT_DETERMINED;
bluetoothAuthorized: string = NOT_DETERMINED;
cameraAuthorized: string = NOT_DETERMINED;
locationAuthorized: string = NOT_DETERMINED;
locationAccuracy: string = NOT_DETERMINED;
microphoneAuthorized: string = NOT_DETERMINED;
notificationAuthorized: string = NOT_DETERMINED;
notificationAlertAuthorized: string = NOT_DETERMINED;
notificationBadgeAuthorized: string = NOT_DETERMINED;
notificationSoundAuthorized: string = NOT_DETERMINED;
phoneCalendarAuthorized: string = NOT_DETERMINED;
}
class GetAppAuthorizeSettingImpl {
accessTokenId: number;
atManager: abilityAccessCtrl.AtManager;
appAuthorizeSetting: AppAuthorizeSetting;
constructor(accessTokenId: number, atManager: abilityAccessCtrl.AtManager, appAuthorizeSetting: AppAuthorizeSetting){
this.accessTokenId = accessTokenId;
this.atManager = atManager;
this.appAuthorizeSetting = appAuthorizeSetting;
this.getAlbumAuthorizeSetting();
this.getBlueToothAuthorizeSetting();
this.getCameraAuthorizeSetting();
this.getLocationAuthorizeSetting();
this.getMicrophoneAuthorizeSetting();
this.getNotificationAuthorizeSetting();
this.getPhoneCalendarAuthorizeSetting();
}
getAlbumAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.READ_IMAGEVIDEO');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.albumAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.albumAuthorized = AUTHORIZED;
}
}
getBlueToothAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.ACCESS_BLUETOOTH');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.bluetoothAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.bluetoothAuthorized = AUTHORIZED;
}
}
getCameraAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.CAMERA');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.cameraAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.cameraAuthorized = AUTHORIZED;
}
}
getLocationAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.LOCATION');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.locationAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.locationAuthorized = AUTHORIZED;
}
}
getMicrophoneAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.MICROPHONE');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.microphoneAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.microphoneAuthorized = AUTHORIZED;
}
}
getNotificationAuthorizeSetting() {
try {
const isNotificationEnabled = notificationManager.isNotificationEnabledSync();
if (isNotificationEnabled) {
this.appAuthorizeSetting.notificationAuthorized = DENIED;
}
if (isNotificationEnabled) {
this.appAuthorizeSetting.notificationAuthorized = AUTHORIZED;
}
} catch (error) {
this.appAuthorizeSetting.notificationAuthorized = DENIED;
}
}
getPhoneCalendarAuthorizeSetting() {
const grantStatus = this.atManager.checkAccessTokenSync(this.accessTokenId, 'ohos.permission.WRITE_CALENDAR');
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.appAuthorizeSetting.phoneCalendarAuthorized = DENIED;
}
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
this.appAuthorizeSetting.phoneCalendarAuthorized = AUTHORIZED;
}
}
}
const getAppAuthorizeSetting: GetAppAuthorizeSetting = defineSyncApi<GetAppAuthorizeSettingResult>('getAppAuthorizeSetting', ()=>{
const bundleInfoWithApplication = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const appAuthorizeSettingImpl = new GetAppAuthorizeSettingImpl(bundleInfoWithApplication.appInfo.accessTokenId, abilityAccessCtrl.createAtManager(), new AppAuthorizeSetting());
return appAuthorizeSettingImpl.appAuthorizeSetting as GetAppAuthorizeSettingResult;
}) as GetAppAuthorizeSetting;
const API_GET_APP_BASE_INFO = 'getAppBaseInfo';
const getBundleInfoOnce = ()=>{
let bundleInfo: bundleManager1.BundleInfo | null = null;
return (): bundleManager1.BundleInfo =>{
if (bundleInfo) {
return bundleInfo;
}
bundleInfo = bundleManager1.getBundleInfoForSelfSync(bundleManager1.BundleFlag.GET_BUNDLE_INFO_DEFAULT);
return bundleInfo;
};
};
const getBundleInfo = getBundleInfoOnce();
const getAppBaseInfo: GetAppBaseInfo = defineSyncApi<GetAppBaseInfoResult>(API_GET_APP_BASE_INFO, (): GetAppBaseInfoResult =>{
const appVersion = UTSHarmony.getAppVersion() as IAppBaseInfoAppVersion;
const appLanguage = I18n.System.getAppPreferredLanguage();
const uniCompilerVersion: string = UTSHarmony.getUniCompilerVersion() as string;
const uniRuntimeVersion: string = UTSHarmony.getUniRuntimeVersion();
return {
appId: UTSHarmony.getAppId() as string,
appLanguage,
appName: UTSHarmony.getAppName() as string,
appTheme: UTSHarmony.getAppTheme() as string,
appVersion: appVersion.name,
appVersionCode: appVersion.code,
appWgtVersion: appVersion.name,
hostLanguage: I18n.System.getSystemLanguage(),
isUniAppX: UTSHarmony.isUniAppX() as boolean,
packageName: getBundleInfo().name,
uniCompilerVersion: uniCompilerVersion,
uniCompilerVersionCode: parseFloat(uniCompilerVersion),
uniRuntimeVersion: uniRuntimeVersion,
uniRuntimeVersionCode: parseFloat(uniRuntimeVersion),
uniPlatform: 'app'
} as GetAppBaseInfoResult;
}) as GetAppBaseInfo;
const API_GET_BACKGROUND_AUDIO_MANAGER = 'getBackgroundAudioManager';
const isFileUri2 = (path: string)=>{
return path && typeof path === 'string' && (path.startsWith('file://') || path.startsWith('datashare://'));
};
const isSandboxPath1 = (path: string)=>{
return path && typeof path === 'string' && path.startsWith('/data/storage/');
};
const getFdFromUriOrSandBoxPath1 = (uri: string)=>{
try {
const file = fileIo1.openSync(uri, fileIo1.OpenMode.READ_ONLY);
return file.fd;
} catch (error) {
console.info(`[AdvancedAPI] Can not get file from uri: ${uri} `);
}
throw new Error('file is not exist');
};
const callCallbacks1 = (callbacks: Function[], ...args: Object[])=>{
callbacks.forEach((cb)=>{
typeof cb === 'function' && cb(...args);
});
};
const remoteCallback1 = (callbacks: Function[], callback: Function)=>{
const index = callbacks.indexOf(callback);
if (index > -1) {
callbacks.splice(index, 1);
}
};
class AudioPlayerError1 {
errMsg: string;
errCode: number;
constructor(errMsg: string, errCode: number){
this.errMsg = errMsg;
this.errCode = errCode;
}
}
class AudioPlayerCallback1 {
onCanplayCallbacks: Function[] = [];
onPlayCallbacks: Function[] = [];
onPauseCallbacks: Function[] = [];
onStopCallbacks: Function[] = [];
onEndedCallbacks: Function[] = [];
onTimeUpdateCallbacks: Function[] = [];
onErrorCallbacks: Function[] = [];
onWaitingCallbacks: Function[] = [];
onSeekingCallbacks: Function[] = [];
onSeekedCallbacks: Function[] = [];
constructor(){}
canPlay() {
callCallbacks1(this.onCanplayCallbacks);
}
onCanplay(callback: Function) {
this.onCanplayCallbacks.push(callback);
}
offCanplay(callback: Function) {
remoteCallback1(this.onCanplayCallbacks, callback);
}
play() {
callCallbacks1(this.onPlayCallbacks);
}
onPlay(callback: Function) {
this.onPlayCallbacks.push(callback);
}
offPlay(callback: Function) {
remoteCallback1(this.onPlayCallbacks, callback);
}
pause() {
callCallbacks1(this.onPauseCallbacks);
}
onPause(callback: Function) {
this.onPauseCallbacks.push(callback);
}
offPause(callback: Function) {
remoteCallback1(this.onPauseCallbacks, callback);
}
stop() {
callCallbacks1(this.onStopCallbacks);
}
onStop(callback: Function) {
this.onStopCallbacks.push(callback);
}
offStop(callback: Function) {
remoteCallback1(this.onStopCallbacks, callback);
}
ended() {
callCallbacks1(this.onEndedCallbacks);
}
onEnded(callback: Function) {
this.onEndedCallbacks.push(callback);
}
offEnded(callback: Function) {
remoteCallback1(this.onEndedCallbacks, callback);
}
timeUpdate(time: number) {
callCallbacks1(this.onTimeUpdateCallbacks, time);
}
onTimeUpdate(callback: Function) {
this.onTimeUpdateCallbacks.push(callback);
}
offTimeUpdate(callback: Function) {
remoteCallback1(this.onTimeUpdateCallbacks, callback);
}
error(res: AudioPlayerError1) {
callCallbacks1(this.onErrorCallbacks, res);
}
onError(callback: Function) {
this.onErrorCallbacks.push(callback);
}
offError(callback: Function) {
remoteCallback1(this.onErrorCallbacks, callback);
}
onPrev(callback: Function) {
console.info('ios only');
}
onNext(callback: Function) {
console.info('ios only');
}
waiting() {
callCallbacks1(this.onWaitingCallbacks);
}
onWaiting(callback: Function) {
this.onWaitingCallbacks.push(callback);
}
offWaiting(callback: Function) {
remoteCallback1(this.onWaitingCallbacks, callback);
}
seeking() {
callCallbacks1(this.onSeekingCallbacks);
}
onSeeking(callback: Function) {
this.onSeekingCallbacks.push(callback);
}
offSeeking(callback: Function) {
remoteCallback1(this.onSeekingCallbacks, callback);
}
seeked() {
callCallbacks1(this.onSeekedCallbacks);
}
onSeeked(callback: Function) {
this.onSeekedCallbacks.push(callback);
}
offSeeked(callback: Function) {
remoteCallback1(this.onSeekedCallbacks, callback);
}
}
const audioPlayerCallback = new AudioPlayerCallback1();
let AV_SESSION: avSession.AVSession | null = null;
const createAVSession = ()=>{
avSession.createAVSession(UTSHarmony.getUIAbilityContext()!, 'player', 'audio').then((data)=>{
AV_SESSION = data;
});
};
const destroyAVSession = ()=>{
if (AV_SESSION === null) {
return;
}
AV_SESSION.destroy();
AV_SESSION = null;
};
const startBackgroundTask = ()=>{
const abilityInfo = UTSHarmony.getUIAbilityContext()!.abilityInfo as TempAbilityInfo;
const wantAgentInfo: wantAgent.WantAgentInfo = {
wants: [
{
bundleName: abilityInfo.bundleName,
abilityName: abilityInfo.name
}
],
operationType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags: [
wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG
]
};
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj)=>{
return backgroundTaskManager.startBackgroundRunning(UTSHarmony.getUIAbilityContext()!, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj);
}).then(()=>{
console.debug('[getBackgroundAudioManager] start bg operation succeeded');
}).catch((err: BusinessError6)=>{
audioPlayerCallback.error(new AudioPlayerError1(err.message, err.code));
});
};
const stopBackgroundTask = ()=>{
backgroundTaskManager.stopBackgroundRunning(UTSHarmony.getUIAbilityContext()!).then(()=>{
console.debug('[getBackgroundAudioManager] stop operation succeeded');
}).catch((err: BusinessError6)=>{
audioPlayerCallback.error(new AudioPlayerError1(err.message, err.code));
});
};
const START_BACKGROUND = ()=>{
startBackgroundTask();
createAVSession();
};
const STOP_BACKGROUND = ()=>{
destroyAVSession();
stopBackgroundTask();
};
const LOG1 = (msg: string)=>console.log(`[getBackgroundAudioManager]: ${msg}`);
class STATE_TYPE1 {
static IDLE: string = 'idle';
static PLAYING: string = 'playing';
static PAUSED: string = 'paused';
static STOPPED: string = 'stopped';
static ERROR: string = 'error';
}
class BackgroundAudioManagerImpl implements BackgroundAudioManager {
static audioPlayer?: media2.AudioPlayer;
private _src: string = '';
private _startTime: number = 0;
private _buffered: number = 0;
private _title: string = '';
private _epname: string = '';
private _singer: string = '';
private _coverImgUrl: string = '';
private _webUrl: string = '';
private _protocol: string = '';
private _playbackRate: number = 1;
readonly obeyMuteSwitch: boolean = false;
constructor(){
this.init();
}
init() {
BackgroundAudioManagerImpl.audioPlayer = media2.createAudioPlayer();
BackgroundAudioManagerImpl.audioPlayer.on('dataLoad', ()=>{
audioPlayerCallback.canPlay();
});
BackgroundAudioManagerImpl.audioPlayer.on('play', ()=>{
audioPlayerCallback.play();
});
BackgroundAudioManagerImpl.audioPlayer.on('pause', ()=>{
audioPlayerCallback.pause();
});
BackgroundAudioManagerImpl.audioPlayer.on('finish', ()=>{
STOP_BACKGROUND();
audioPlayerCallback.ended();
});
BackgroundAudioManagerImpl.audioPlayer.on('timeUpdate', (res)=>{
audioPlayerCallback.timeUpdate(res / 1000);
});
BackgroundAudioManagerImpl.audioPlayer.on('error', (err)=>{
audioPlayerCallback.error(new AudioPlayerError1(err.message, err.code));
});
BackgroundAudioManagerImpl.audioPlayer.on('bufferingUpdate', (infoType, value)=>{
console.info(`[AdvancedAPI] audioPlayer bufferingUpdate ${infoType} ${value}`);
if (infoType === media2.BufferingInfoType.BUFFERING_PERCENT && value !== 0 && BackgroundAudioManagerImpl.audioPlayer) {
this._buffered = value;
if ((BackgroundAudioManagerImpl.audioPlayer.currentTime / 1000) >= (BackgroundAudioManagerImpl.audioPlayer.duration * value / 100000)) {
audioPlayerCallback.waiting();
}
}
});
BackgroundAudioManagerImpl.audioPlayer.on('audioInterrupt', (InterruptEvent)=>{
console.info('[AdvancedAPI] audioInterrupt:' + JSON.stringify(InterruptEvent));
if (BackgroundAudioManagerImpl.audioPlayer && InterruptEvent.hintType === audio1.InterruptHint.INTERRUPT_HINT_PAUSE) {
BackgroundAudioManagerImpl.audioPlayer.pause();
}
if (BackgroundAudioManagerImpl.audioPlayer && InterruptEvent.hintType === audio1.InterruptHint.INTERRUPT_HINT_RESUME) {
BackgroundAudioManagerImpl.audioPlayer.play();
}
});
}
get duration() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return 0;
}
return BackgroundAudioManagerImpl.audioPlayer.duration / 1000;
}
get currentTime() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return 0;
}
return BackgroundAudioManagerImpl.audioPlayer.currentTime / 1000;
}
get paused() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return false;
}
return BackgroundAudioManagerImpl.audioPlayer.state === STATE_TYPE1.PAUSED;
}
get src() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return '';
}
return BackgroundAudioManagerImpl.audioPlayer.src;
}
set src(value) {
if (typeof value !== 'string') {
audioPlayerCallback.error(new AudioPlayerError1(`set src: ${value} is not string`, 10004));
return;
}
if (!BackgroundAudioManagerImpl.audioPlayer) {
audioPlayerCallback.error(new AudioPlayerError1(`player is not exist`, 10001));
return;
}
if (!value || !(value.startsWith('http:') || value.startsWith('https:') || isFileUri2(value) || isSandboxPath1(value))) {
LOG1(`set src: ${value} is invalid`);
return;
}
let path: string = '';
if (value.startsWith('http:') || value.startsWith('https:')) {
path = value;
} else if (isFileUri2(value) || isSandboxPath1(value)) {
try {
const fd = getFdFromUriOrSandBoxPath1(value);
path = `fd://${fd}`;
} catch (err) {
audioPlayerCallback.error(new AudioPlayerError1((err as BusinessError6).message, (err as BusinessError6).code));
}
}
if (BackgroundAudioManagerImpl.audioPlayer.src && path !== BackgroundAudioManagerImpl.audioPlayer.src) {
BackgroundAudioManagerImpl.audioPlayer.reset();
}
BackgroundAudioManagerImpl.audioPlayer.src = path;
this._src = value;
if (this._startTime) {
BackgroundAudioManagerImpl.audioPlayer.seek(this._startTime);
}
BackgroundAudioManagerImpl.audioPlayer.play();
START_BACKGROUND();
}
get startTime() {
return this._startTime / 1000;
}
set startTime(time: number) {
this._startTime = time * 1000;
}
get title() {
return this._title;
}
set title(titleName: string) {
this._title = titleName;
}
get buffered() {
if (!BackgroundAudioManagerImpl.audioPlayer) return 0;
return BackgroundAudioManagerImpl.audioPlayer.duration * this._buffered / 100000;
}
get epname() {
return this._epname;
}
set epname(epName: string) {
this._epname = epName;
}
get singer() {
return this._singer;
}
set singer(singerName: string) {
this._singer = singerName;
}
get coverImgUrl() {
return this._coverImgUrl;
}
set coverImgUrl(url: string) {
this._coverImgUrl = url;
}
get webUrl() {
return this._webUrl;
}
set webUrl(url: string) {
this._webUrl = url;
}
get protocol() {
return this._protocol;
}
set protocol(protocolType: string) {
this._protocol = protocolType;
}
set playbackRate(rate: number) {
audioPlayerCallback.error(new AudioPlayerError1('HarmonyOS Next Audio setting playbackRate is not supported.', -1));
}
get playbackRate() {
return this._playbackRate;
}
play() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return;
}
const state = BackgroundAudioManagerImpl.audioPlayer.state;
if (![
STATE_TYPE1.PAUSED,
STATE_TYPE1.STOPPED,
STATE_TYPE1.IDLE
].includes(state)) {
return;
}
if (this._src && BackgroundAudioManagerImpl.audioPlayer.src === '') {
this.src = this._src;
}
BackgroundAudioManagerImpl.audioPlayer.play();
START_BACKGROUND();
}
pause() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return;
}
const state = BackgroundAudioManagerImpl.audioPlayer.state;
if (STATE_TYPE1.PLAYING !== state) {
return;
}
BackgroundAudioManagerImpl.audioPlayer.pause();
}
stop() {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return;
}
if (![
STATE_TYPE1.PAUSED,
STATE_TYPE1.PLAYING
].includes(BackgroundAudioManagerImpl.audioPlayer.state)) {
return;
}
BackgroundAudioManagerImpl.audioPlayer.stop();
BackgroundAudioManagerImpl.audioPlayer.release();
this.init();
STOP_BACKGROUND();
audioPlayerCallback.stop();
}
seek(position: number) {
if (!BackgroundAudioManagerImpl.audioPlayer) {
return;
}
const state = BackgroundAudioManagerImpl.audioPlayer.state;
if (![
STATE_TYPE1.PAUSED,
STATE_TYPE1.PLAYING
].includes(state)) {
return;
}
BackgroundAudioManagerImpl.audioPlayer.seek(position * 1000);
}
onCanplay(callback: (result: Object) => void): void {
audioPlayerCallback.onCanplay(callback);
}
onPlay(callback: (result: Object) => void): void {
audioPlayerCallback.onPlay(callback);
}
onPause(callback: (result: Object) => void): void {
audioPlayerCallback.onPause(callback);
}
onStop(callback: (result: Object) => void): void {
audioPlayerCallback.onStop(callback);
}
onEnded(callback: (result: Object) => void): void {
audioPlayerCallback.onEnded(callback);
}
onTimeUpdate(callback: (result: Object) => void): void {
audioPlayerCallback.onTimeUpdate(callback);
}
onError(callback: (result: ICreateBackgroundAudioFail) => void): void {
audioPlayerCallback.onError(callback);
}
onWaiting(callback: (result: Object) => void): void {
audioPlayerCallback.onWaiting(callback);
}
offCanplay(callback: (result: Object) => void): void {
audioPlayerCallback.offCanplay(callback);
}
offPlay(callback: (result: Object) => void): void {
audioPlayerCallback.offPlay(callback);
}
offPause(callback: (result: Object) => void): void {
audioPlayerCallback.offPause(callback);
}
offStop(callback: (result: Object) => void): void {
audioPlayerCallback.offStop(callback);
}
offEnded(callback: (result: Object) => void): void {
audioPlayerCallback.offEnded(callback);
}
offTimeUpdate(callback: (result: Object) => void): void {
audioPlayerCallback.offTimeUpdate(callback);
}
offError(callback: (result: ICreateBackgroundAudioFail) => void): void {
audioPlayerCallback.offError(callback);
}
offWaiting(callback: (result: Object) => void): void {
audioPlayerCallback.offWaiting(callback);
}
onPrev(callback: (result: Object) => void): void {
throw new Error('Method not implemented.');
}
onNext(callback: (result: Object) => void): void {
throw new Error('Method not implemented.');
}
onSeeking(callback: (result: Object) => void): void {
throw new Error('Method not implemented.');
}
onSeeked(callback: (result: Object) => void): void {
throw new Error('Method not implemented.');
}
}
let backgroundAudioManager: BackgroundAudioManager | null = null;
const getBackgroundAudioManager: GetBackgroundAudioManager = defineSyncApi<BackgroundAudioManager>(API_GET_BACKGROUND_AUDIO_MANAGER, ()=>{
if (!backgroundAudioManager) backgroundAudioManager = new BackgroundAudioManagerImpl();
return backgroundAudioManager;
}) as GetBackgroundAudioManager;
const API_GET_DEVICE_INFO = 'getDeviceInfo';
const parseDeviceType = (deviceType: string): 'phone' | 'pad' | 'tv' | 'watch' | 'pc' | 'unknown' | 'car' | 'vr' | 'appliance' =>{
switch(deviceType){
case 'phone':
return 'phone';
case 'wearable':
return 'watch';
case 'tablet':
return 'pad';
case '2in1':
return 'pc';
case 'tv':
return 'tv';
case 'car':
return 'car';
case 'smartVision':
return 'vr';
default:
return 'unknown';
}
};
const getDeviceInfo: GetDeviceInfo = defineSyncApi<GetDeviceInfoResult>(API_GET_DEVICE_INFO, (): GetDeviceInfoResult =>{
return {
deviceBrand: deviceInfo.brand.toLowerCase(),
deviceId: getDeviceId(),
deviceModel: deviceInfo.productModel,
deviceOrientation: 'portrait',
devicePixelRatio: vp2px(1),
deviceType: parseDeviceType(deviceInfo.deviceType),
osLanguage: I18n1.System.getSystemLanguage(),
osTheme: UTSHarmony.getOsTheme() as string,
osVersion: deviceInfo.majorVersion + '.' + deviceInfo.seniorVersion + '.' + deviceInfo.featureVersion + '.' + deviceInfo.buildVersion,
osName: 'harmonyos',
platform: 'harmonyos',
romName: deviceInfo.distributionOSName,
romVersion: deviceInfo.distributionOSVersion,
system: deviceInfo.osFullName
} as GetDeviceInfoResult;
}) as GetDeviceInfo;
const API_GET_NETWORK_TYPE = 'getNetworkType';
const PERMISSIONS1 = [
'ohos.permission.GET_NETWORK_INFO'
];
enum NetworkinfoType {
UNKNOW = 0,
NONE = 1,
ETHERNET = 2,
WIFI = 3,
"2G" = 4,
"3G" = 5,
"4G" = 6,
"5G" = 7
}
const signalType = (resultObj: radio.NetworkType)=>{
switch(resultObj){
case radio.NetworkType.NETWORK_TYPE_GSM:
case radio.NetworkType.NETWORK_TYPE_CDMA:
return NetworkinfoType['2G'];
case radio.NetworkType.NETWORK_TYPE_WCDMA:
case radio.NetworkType.NETWORK_TYPE_TDSCDMA:
return NetworkinfoType['3G'];
case radio.NetworkType.NETWORK_TYPE_LTE:
return NetworkinfoType['4G'];
case radio.NetworkType.NETWORK_TYPE_NR:
return NetworkinfoType['5G'];
case radio.NetworkType.NETWORK_TYPE_UNKNOWN:
return NetworkinfoType.UNKNOW;
default:
return NetworkinfoType.NONE;
}
};
const networkGetType = ()=>{
return new Promise<number>((resolve, reject)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS1, (allRight: boolean)=>{
if (allRight) {
try {
radio.getPrimarySlotId().then((slotId: number)=>radio.getSignalInformationSync(slotId)).then((signalInformation: Array<radio.SignalInformation>)=>{
const data = signalInformation[0];
if (data && data.signalType) {
resolve(signalType(data.signalType));
} else {
resolve(NetworkinfoType.NONE);
}
});
} catch (error) {
reject(error as BusinessError7);
}
} else {
reject('permission denied');
}
}, ()=>reject('permission denied'));
});
};
class GlobalContext {
netList: connection.NetHandle[] = [];
netHandle: connection.NetHandle | null = null;
private constructor(){}
private static instance: GlobalContext;
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
}
const getCurrentType = ()=>{
return new Promise<number>((resolve, reject)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS1, (allRight: boolean)=>{
if (allRight) {
try {
connection.getDefaultNet().then((data: connection.NetHandle)=>{
if (data) {
GlobalContext.getContext().netHandle = data;
connection.getNetCapabilities(GlobalContext.getContext().netHandle!).then((data: connection.NetCapabilities)=>{
const bearerTypes: Set<number> = new Set(data.bearerTypes);
const bearerTypesNum = Array.from(bearerTypes.values());
for (const item of bearerTypesNum){
if (item == connection.NetBearType.BEARER_CELLULAR) {
networkGetType().then(resolve).catch(reject);
} else if (item == connection.NetBearType.BEARER_WIFI) {
resolve(NetworkinfoType.WIFI);
} else if (item == connection.NetBearType.BEARER_ETHERNET) {
resolve(NetworkinfoType.ETHERNET);
} else {
resolve(NetworkinfoType.UNKNOW);
}
}
}).catch((err: BusinessError7)=>{
reject(err);
});
}
});
} catch (error) {
reject(error);
}
} else {
reject('permission denied');
}
});
});
};
class Network {
static netConnection: connection.NetConnection | null = null;
constructor(){
Network.netConnection = connection.createNetConnection();
}
static ohoSubscribe() {
if (!Network.netConnection) {
Network.netConnection = connection.createNetConnection();
}
UTSHarmony.requestSystemPermission(PERMISSIONS1, (allRight: boolean)=>{
if (allRight && Network.netConnection) {
Network.netConnection.register((err: BusinessError7)=>{});
Network.netConnection.on('netCapabilitiesChange', (capability: connection.NetCapabilityInfo)=>{
const NetBearType = capability?.netCap?.bearerTypes[0];
let networkType = '';
switch(NetBearType){
case connection.NetBearType.BEARER_CELLULAR:
getCurrentType().then((type: number)=>{
invokeOnNetworkStatusChange(NetworkinfoType[type]);
}).catch(()=>{
invokeOnNetworkStatusChange(NetworkinfoType[1]);
});
return;
case connection.NetBearType.BEARER_WIFI:
networkType = NetworkinfoType[3];
break;
case connection.NetBearType.BEARER_ETHERNET:
networkType = NetworkinfoType[2];
break;
default:
networkType = NetworkinfoType[1];
}
invokeOnNetworkStatusChange(networkType);
});
Network.netConnection.on('netLost', (netLost: connection.NetHandle)=>{
invokeOnNetworkStatusChange(NetworkinfoType[1]);
});
}
});
}
}
new Network();
onNativePageReady().then(()=>{
Network.ohoSubscribe();
});
const getNetworkType: GetNetworkType = defineAsyncApi<GetNetworkTypeOptions, GetNetworkTypeSuccess>(API_GET_NETWORK_TYPE, (options: GetNetworkTypeOptions, res: ApiExecutor<GetNetworkTypeSuccess>)=>{
getCurrentType().then((type: number)=>{
res.resolve({
networkType: NetworkinfoType[type].toLocaleLowerCase()
} as GetNetworkTypeSuccess);
}).catch((err: BusinessError7)=>{
if (err.code === 2100001) {
res.resolve({
networkType: NetworkinfoType[1].toLocaleLowerCase()
} as GetNetworkTypeSuccess);
} else {
res.reject(err.message);
}
});
}) as GetNetworkType;
const invokeOnNetworkStatusChange = (networkType: string)=>{
UniGetNetworkTypeEventEmitter.emit('networkStatusChange', {
isConnected: networkType !== NetworkinfoType[1],
networkType: networkType.toLocaleLowerCase()
} as OnNetworkStatusChangeCallbackResult);
};
const UniGetNetworkTypeEventEmitter = new Emitter1() as IUniGetNetworkTypeEventEmitter;
const onNetworkStatusChange: OnNetworkStatusChange = (callback: Function)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS1, (allRight: boolean)=>{
if (allRight) {
UniGetNetworkTypeEventEmitter.on('networkStatusChange', callback);
}
});
};
const offNetworkStatusChange: OffNetworkStatusChange = (callback: Function)=>{
UTSHarmony.requestSystemPermission(PERMISSIONS1, (allRight: boolean)=>{
if (allRight) {
UniGetNetworkTypeEventEmitter.off('networkStatusChange', callback);
}
});
};
const API_GET_PROVIDER = 'getProvider';
const API_GET_PROVIDER_SYNC = 'getProviderSync';
const SupportedProviderServiceList = [
'oauth',
'share',
'payment',
'push',
'location'
];
const _getProviderSync = (options: GetProviderOptions)=>{
if (!SupportedProviderServiceList.includes(options.service)) {
return 'Parameter service invalid.';
}
const providers = getUniProviders(options.service);
const providerIds = providers.map((provider): string =>{
return provider.id;
});
const result: GetProviderSuccess = {
service: options.service,
provider: providerIds,
providers
};
return result;
};
const getProvider: GetProvider = defineAsyncApi<GetProviderOptions, GetProviderSuccess>(API_GET_PROVIDER, (options: GetProviderOptions, exec: ApiExecutor<GetProviderSuccess>): void =>{
const res = _getProviderSync(options);
if (typeof res === 'string') exec.reject(res);
else exec.resolve(res);
}) as GetProvider;
const getProviderSync: GetProviderSync = defineSyncApi<GetProviderSyncSuccess>(API_GET_PROVIDER_SYNC, (options: GetProviderSyncOptions): GetProviderSyncSuccess =>{
const res = _getProviderSync(options as GetProviderOptions);
if (typeof res === 'string') throw new Error(res);
return {
service: res.service,
providerIds: res.provider,
providerObjects: res.providers
} as GetProviderSyncSuccess;
}) as GetProviderSync;
const API_GET_RECORDER_MANAGER = 'getRecorderManager';
const callbacks: Callbacks = {
pause: undefined,
resume: undefined,
start: undefined,
stop: undefined,
error: undefined,
frameRecorded: undefined,
interruptionBegin: undefined,
interruptionEnd: undefined
};
const setRecordStateCallback = (state: RecorderState, cb: Function)=>{
switch(state){
case 'pause':
callbacks.pause = cb;
break;
case 'resume':
callbacks.resume = cb;
break;
case 'start':
callbacks.start = cb;
break;
case 'stop':
callbacks.stop = cb;
break;
case 'error':
callbacks.error = cb;
break;
case 'frameRecorded':
callbacks.frameRecorded = cb;
break;
case 'interruptionBegin':
callbacks.interruptionBegin = cb;
break;
case 'interruptionEnd':
callbacks.interruptionEnd = cb;
break;
}
};
const onRecorderStateChange = (state: RecorderState, res: StateChangeRes | null = null): void =>{
switch(state){
case 'pause':
return callbacks.pause?.(res);
case 'resume':
return callbacks.resume?.(res);
case 'start':
return callbacks.start?.(res);
case 'stop':
return callbacks.stop?.(res);
case 'error':
return callbacks.error?.(res);
case 'frameRecorded':
return callbacks.frameRecorded?.(res);
case 'interruptionBegin':
return callbacks.interruptionBegin?.(res);
case 'interruptionEnd':
return callbacks.interruptionEnd?.(res);
}
};
const createFile = (supportFormats: string[], format: string, defaultExt: string)=>{
const TEMP_PATH = getEnv3().TEMP_PATH as string;
const filePath = `${TEMP_PATH}/recorder/`;
if (!fileIo2.accessSync(filePath)) {
fileIo2.mkdirSync(filePath, true);
}
const fileName = `${Date.now()}.${supportFormats.includes(format ?? '') ? format?.toLocaleLowerCase() : defaultExt}`;
const file: fileIo2.File = fileIo2.openSync(`${filePath}${fileName}`, fileIo2.OpenMode.READ_WRITE | fileIo2.OpenMode.CREATE);
return file;
};
const permissionDenied = ()=>{
throw new Error('Permission MICROPHONE denied');
};
const supportFormats = [
'aac'
];
class AVRecorder implements RecorderManager {
private avRecorder?: media3.AVRecorder;
private isFirstStart: boolean = true;
constructor(){}
private onStateChange(file: fileIo3.File) {
if (this.avRecorder) {
this.avRecorder.on('stateChange', async (state, reason)=>{
switch(state){
case 'idle':
this.isFirstStart = true;
break;
case 'started':
if (this.isFirstStart) {
this.isFirstStart = false;
onRecorderStateChange('start');
} else {
if (reason === media3.StateChangeReason.BACKGROUND) {
onRecorderStateChange('interruptionEnd');
}
onRecorderStateChange('resume');
}
break;
case 'paused':
if (reason === media3.StateChangeReason.BACKGROUND) {
onRecorderStateChange('interruptionBegin');
}
onRecorderStateChange('pause');
break;
case 'stopped':
onRecorderStateChange('stop', {
tempFilePath: file.path
} as StateChangeRes);
fileIo3.closeSync(file);
break;
}
});
this.avRecorder.on('error', (err: BusinessError8)=>{
onRecorderStateChange('error', {
errMsg: `${err.message} ${err.code}`
} as StateChangeRes);
});
}
}
private async release() {
if (this.avRecorder !== undefined) {
await this.avRecorder.reset();
await this.avRecorder.release();
this.avRecorder = undefined;
}
}
async start(options: RecorderManagerStartOptions): Promise<void> {
if (this.avRecorder !== undefined) {
await this.release();
}
this.avRecorder = await media3.createAVRecorder();
const _options_sampleRate = options.sampleRate, sampleRate = _options_sampleRate == null ? 48000 : _options_sampleRate, _options_numberOfChannels = options.numberOfChannels, numberOfChannels = _options_numberOfChannels == null ? 2 : _options_numberOfChannels, _options_encodeBitRate = options.encodeBitRate, encodeBitRate = _options_encodeBitRate == null ? 48000 : _options_encodeBitRate, _options_duration = options.duration, duration = _options_duration == null ? null : _options_duration;
const file = createFile(supportFormats, options.format ?? '', 'aac');
this.onStateChange(file);
const audioProfile: media3.AVRecorderProfile = {
audioBitrate: encodeBitRate!,
audioChannels: numberOfChannels!,
audioCodec: media3.CodecMimeType.AUDIO_AAC,
audioSampleRate: sampleRate!,
fileFormat: media3.ContainerFormatType.CFT_MPEG_4A
};
const audioConfig: media3.AVRecorderConfig = {
audioSourceType: media3.AudioSourceType.AUDIO_SOURCE_TYPE_MIC,
profile: audioProfile,
url: 'fd://' + file.fd
};
UTSHarmony.requestSystemPermission([
'ohos.permission.MICROPHONE'
], async (allRight: boolean)=>{
if (allRight) {
await this.avRecorder?.prepare(audioConfig);
await this.avRecorder?.start();
if (duration) {
setTimeout(async ()=>{
await this.avRecorder?.stop();
}, duration);
}
} else {
permissionDenied();
}
}, permissionDenied);
}
async pause(): Promise<void> {
if (this.avRecorder !== undefined && this.avRecorder.state === 'started') {
await this.avRecorder.pause();
}
}
async resume(): Promise<void> {
if (this.avRecorder !== undefined && this.avRecorder.state === 'paused') {
await this.avRecorder.resume();
}
}
async stop(): Promise<void> {
if (this.avRecorder !== undefined && (this.avRecorder.state === 'started' || this.avRecorder.state === 'paused')) {
await this.avRecorder.stop();
await this.release();
this.isFirstStart = true;
}
}
onStart(options: (result: Object) => void): void {
setRecordStateCallback('start', options);
}
onPause(options: (result: Object) => void): void {
setRecordStateCallback('pause', options);
}
onStop(options: (result: RecorderManagerOnStopResult) => void): void {
setRecordStateCallback('stop', options);
}
onFrameRecorded(options: (result: Object) => void): void {
setRecordStateCallback('frameRecorded', options);
}
onError(options: (result: Object) => void): void {
setRecordStateCallback('error', options);
}
onResume(options: (result: Object) => void): void {
setRecordStateCallback('resume', options);
}
onInterruptionBegin(options: (result: Object) => void): void {
setRecordStateCallback('interruptionBegin', options);
}
onInterruptionEnd(options: (result: Object) => void): void {
setRecordStateCallback('interruptionEnd', options);
}
}
let RECORDER_MANAGER: AVRecorder | null = null;
const DEFAULT_DURATION = 60000;
const MAX_DURATION = 60000 * 10;
const DEFAULT_FORMAT = 'aac';
class RecorderManagerImpl implements RecorderManager {
start(options: RecorderManagerStartOptions | null = null): void {
if (options == null) options = {} as RecorderManagerStartOptions;
if (!options.format) options.format = DEFAULT_FORMAT;
if (options.duration == null) {
options.duration = DEFAULT_DURATION;
}
if (options.duration > MAX_DURATION) {
options.duration = MAX_DURATION;
}
if (supportFormats.includes(options.format ?? '')) {
RECORDER_MANAGER = new AVRecorder();
}
if (RECORDER_MANAGER) {
RECORDER_MANAGER.start(options);
} else {
onRecorderStateChange('error', {
errMsg: `format not supported. Only supported ${supportFormats.join(',')}`
} as StateChangeRes);
}
}
pause(): void {
if (RECORDER_MANAGER) RECORDER_MANAGER.pause();
}
resume(): void {
if (RECORDER_MANAGER) RECORDER_MANAGER.resume();
}
async stop() {
if (RECORDER_MANAGER) {
try {
await RECORDER_MANAGER.stop();
} catch (error) {}
RECORDER_MANAGER = null;
}
}
onStart(options: (result: Object) => void): void {
setRecordStateCallback('start', options);
}
onPause(options: (result: Object) => void): void {
setRecordStateCallback('pause', options);
}
onStop(options: (result: RecorderManagerOnStopResult) => void): void {
setRecordStateCallback('stop', options);
}
onFrameRecorded(options: (result: Object) => void): void {
setRecordStateCallback('frameRecorded', options);
}
onError(options: (result: Object) => void): void {
setRecordStateCallback('error', options);
}
onResume(options: (result: Object) => void): void {
setRecordStateCallback('resume', options);
}
onInterruptionBegin(options: (result: Object) => void): void {
setRecordStateCallback('interruptionBegin', options);
}
onInterruptionEnd(options: (result: Object) => void): void {
setRecordStateCallback('interruptionEnd', options);
}
}
let recorderManager: RecorderManager | null = null;
const getRecorderManager: GetRecorderManager = defineSyncApi<RecorderManager>(API_GET_RECORDER_MANAGER, (): RecorderManager =>{
if (recorderManager) return recorderManager;
else recorderManager = new RecorderManagerImpl();
return recorderManager;
}) as GetRecorderManager;
const API_GET_SYSTEM_INFO = 'getSystemInfo';
const API_GET_SYSTEM_INFO_SYNC = 'getSystemInfoSync';
const API_GET_WINDOW_INFO = 'getWindowInfo';
const parseDeviceType1 = (deviceType: string): 'phone' | 'pad' | 'tv' | 'watch' | 'pc' | 'unknown' | 'car' | 'vr' | 'appliance' =>{
switch(deviceType){
case 'phone':
return 'phone';
case 'wearable':
return 'watch';
case 'tablet':
return 'pad';
case '2in1':
return 'pc';
case 'tv':
return 'tv';
case 'car':
return 'car';
case 'smartVision':
return 'vr';
default:
return 'unknown';
}
};
const getWindowInfo: GetWindowInfo = defineSyncApi<GetWindowInfoResult>(API_GET_WINDOW_INFO, (): GetWindowInfoResult =>{
return internalGetWindowInfo() as GetWindowInfoResult;
}) as GetWindowInfo;
const internalGetSystemInfo = (): GetSystemInfoResult =>{
const appVersion = UTSHarmony.getAppVersion() as ISystemInfoAppVersion;
const appLanguage = I18n2.System.getAppPreferredLanguage();
const uniCompilerVersion: string = UTSHarmony.getUniCompilerVersion() as string;
const uniCompilerVersionCode: number = parseFloat(uniCompilerVersion);
const uniRuntimeVersion: string = UTSHarmony.getUniRuntimeVersion();
const windowInfo = internalGetWindowInfo() as GetWindowInfoResult;
const pixelRatio = windowInfo.pixelRatio;
const safeArea = windowInfo.safeArea;
const safeAreaInsets = windowInfo.safeAreaInsets;
const screenHeight = windowInfo.screenHeight;
const screenWidth = windowInfo.screenWidth;
const statusBarHeight = windowInfo.statusBarHeight;
const windowBottom = windowInfo.windowBottom;
const windowHeight = windowInfo.windowHeight;
const windowTop = windowInfo.windowTop;
const windowWidth = windowInfo.windowWidth;
return {
appId: UTSHarmony.getAppId() as string,
appLanguage,
appName: UTSHarmony.getAppName() as string,
appTheme: UTSHarmony.getAppTheme() as string,
appVersion: appVersion.name,
appVersionCode: appVersion.code,
appWgtVersion: appVersion.name,
uniCompilerVersion: uniCompilerVersion,
uniCompilerVersionCode: uniCompilerVersionCode,
uniRuntimeVersion: uniRuntimeVersion,
uniRuntimeVersionCode: parseFloat(uniRuntimeVersion),
uniPlatform: 'app',
deviceBrand: deviceInfo1.brand.toLowerCase(),
deviceId: getDeviceId1(),
deviceModel: deviceInfo1.productModel,
deviceOrientation: 'portrait',
devicePixelRatio: vp2px(1),
deviceType: parseDeviceType1(deviceInfo1.deviceType),
osLanguage: I18n2.System.getSystemLanguage(),
osTheme: UTSHarmony.getOsTheme() as string,
osVersion: deviceInfo1.majorVersion + '.' + deviceInfo1.seniorVersion + '.' + deviceInfo1.featureVersion + '.' + deviceInfo1.buildVersion,
osName: 'harmonyos',
romName: deviceInfo1.distributionOSName,
romVersion: deviceInfo1.distributionOSVersion,
system: deviceInfo1.osFullName,
pixelRatio,
safeArea,
safeAreaInsets,
screenHeight,
screenWidth,
statusBarHeight,
windowBottom,
windowHeight,
windowTop,
windowWidth,
SDKVersion: '',
browserName: '',
browserVersion: '',
ua: '',
language: appLanguage,
brand: deviceInfo1.brand,
model: '',
platform: 'harmonyos',
uniCompileVersion: uniCompilerVersion,
uniCompileVersionCode: uniCompilerVersionCode,
version: ''
} as GetSystemInfoResult;
};
const getSystemInfoSync: GetSystemInfoSync = defineSyncApi<GetSystemInfoResult>(API_GET_SYSTEM_INFO_SYNC, (): GetSystemInfoResult =>{
return internalGetSystemInfo();
}) as GetSystemInfoSync;
const getSystemInfo: GetSystemInfo = defineAsyncApi<GetSystemInfoOptions, GetSystemInfoResult>(API_GET_SYSTEM_INFO, (options: GetSystemInfoOptions, exec: ApiExecutor<GetSystemInfoResult>)=>{
try {
exec.resolve(internalGetSystemInfo());
} catch (error) {
exec.reject((error as Error).message);
}
}) as GetSystemInfo;
const getSystemSetting: GetSystemSetting = defineSyncApi<GetSystemSettingResult>('getSystemSetting', (): GetSystemSettingResult =>{
const defaultDisplay = display.getDefaultDisplaySync();
const res: GetSystemSettingResult = {
bluetoothEnabled: false,
bluetoothError: null,
locationEnabled: false,
wifiEnabled: false,
wifiError: null,
deviceOrientation: (defaultDisplay.orientation === display.Orientation.PORTRAIT || defaultDisplay.orientation === display.Orientation.PORTRAIT_INVERTED) ? 'portrait' : 'landscape'
};
try {
if (access.getState() === access.BluetoothState.STATE_ON) res.bluetoothEnabled = true;
} catch (err) {
res.bluetoothError = (err as BusinessError9).message;
}
try {
res.locationEnabled = geoLocationManager.isLocationEnabled();
} catch (err) {}
try {
res.wifiEnabled = wifiManager.isWifiActive();
} catch (err) {
res.wifiError = (err as BusinessError9).message;
}
return res;
}) as GetSystemSetting;
const API_HIDE_KEYBOARD = 'hideKeyboard';
const hideKeyboard: HideKeyboard = defineAsyncApi<HideKeyboardOptions, HideKeyboardSuccess>(API_HIDE_KEYBOARD, (options: HideKeyboardOptions, exec: ApiExecutor<HideKeyboardSuccess>)=>{
inputMethod.getController().hideTextInput().then(()=>{
exec.resolve();
}, (err: Error)=>{
exec.reject(err.message);
});
}) as HideKeyboard;
const API_MAKE_PHONE_CALL = 'makePhoneCall';
const MakePhoneCallProtocol = new Map<string, ProtocolOptions>([
[
'phoneNumber',
{
type: 'string',
required: true
}
]
]);
const isPromise = (res: Object)=>{
if ((typeof res === "object" || typeof res === "function") && typeof (res as Promise<void>).then === "function") {
return true;
}
return false;
};
const dial = (number: string, confirm = true)=>{
if (!confirm && typeof call.dial === 'function') {
return new Promise<void>((resolve, reject)=>{
UTSHarmony.requestSystemPermission([
'ohos.permission.PLACE_CALL'
], (allRight: boolean)=>{
if (allRight) {
call.dial(number).then(()=>{
resolve();
}).catch(reject);
} else {
reject('permission denied');
}
}, ()=>{
reject('permission denied');
});
});
} else {
return call.makeCall(number);
}
};
const makePhoneCall: MakePhoneCall = defineAsyncApi<MakePhoneCallOptions, MakePhoneCallSuccess>(API_MAKE_PHONE_CALL, (options: MakePhoneCallOptions, res: ApiExecutor<MakePhoneCallSuccess>)=>{
const dialRes = dial(options.phoneNumber) as Object as Promise<void>;
if (isPromise(dialRes)) {
dialRes.then(res.resolve).catch((err: BusinessError10<void>)=>{
res.reject(err.message);
});
} else {
res.resolve();
}
}, MakePhoneCallProtocol) as MakePhoneCall;
const API_GET_IMAGE_INFO = 'getImageInfo';
const GetImageInfoApiProtocol = new Map<string, ProtocolOptions>([
[
'src',
{
type: 'string',
required: true
}
]
]);
const GetImageInfoApiOptions: ApiOptions<GetImageInfoOptions> = {
formatArgs: new Map<string, Function>([
[
'src',
(src: string, params: GetImageInfoOptions)=>{
params.src = getRealPath2(src);
}
]
])
};
const API_CHOOSE_IMAGE = 'chooseImage';
const ChooseImageApiProtocol = new Map<string, ProtocolOptions>([
[
'count',
{
type: 'number',
required: false
}
],
[
'sizeType',
{
type: 'array',
required: false
}
],
[
'sourceType',
{
type: 'array',
required: false
}
],
[
'extension',
{
type: 'array',
required: false
}
]
]);
const ChooseImageApiOptions: ApiOptions<ChooseImageOptions> = {
formatArgs: new Map<string, Function>([
[
'count',
(count: number, params: ChooseImageOptions)=>{
if (count == null) {
params.count = 9;
}
}
],
[
'sizeType',
(sizeType: string[], params: ChooseImageOptions)=>{
if (sizeType == null) {
params.sizeType = [
'original',
'compressed'
];
}
}
],
[
'sourceType',
(sourceType: string[], params: ChooseImageOptions)=>{
if (sourceType == null) {
params.sourceType = [
'album',
'camera'
];
}
}
],
[
'extension',
(extension: string[], params: ChooseImageOptions)=>{
if (extension == null) {
params.extension = [
'*'
];
}
}
]
])
};
const API_GET_VIDEO_INFO = 'getVideoInfo';
const GetVideoInfoApiProtocol = new Map<string, ProtocolOptions>([
[
'src',
{
type: 'string',
required: true
}
]
]);
const GetVideoInfoApiOptions: ApiOptions<GetVideoInfoOptions> = {
formatArgs: new Map<string, Function>([
[
'src',
(src: string, params: GetVideoInfoOptions)=>{
params.src = getRealPath2(src);
}
]
])
};
const API_CHOOSE_VIDEO = 'chooseVideo';
const ChooseVideoApiProtocol = new Map<string, ProtocolOptions>([
[
'sourceType',
{
type: 'array',
required: false
}
],
[
'compressed',
{
type: 'boolean',
required: false
}
],
[
'maxDuration',
{
type: 'number',
required: false
}
],
[
'camera',
{
type: 'string',
required: false
}
],
[
'extension',
{
type: 'array',
required: false
}
]
]);
const ChooseVideoApiOptions: ApiOptions<ChooseVideoOptions> = {
formatArgs: new Map<string, Function>([
[
'sourceType',
(sourceType: string[], params: ChooseVideoOptions)=>{
if (sourceType == null) {
params.sourceType = [
'album',
'camera'
];
}
}
],
[
'compressed',
(compressed: boolean, params: ChooseVideoOptions)=>{
if (compressed == null) {
params.compressed = true;
}
}
],
[
'maxDuration',
(maxDuration: number, params: ChooseVideoOptions)=>{
if (maxDuration == null) {
params.maxDuration = 60;
}
}
],
[
'camera',
(camera: string, params: ChooseVideoOptions)=>{
if (camera == null) {
params.camera = 'back';
}
}
],
[
'extension',
(extension: string[], params: ChooseVideoOptions)=>{
if (extension == null) {
params.extension = [
'*'
];
}
}
]
])
};
const API_PREVIEW_IMAGE = 'previewImage';
const PreviewImageApiProtocol = new Map<string, ProtocolOptions>([
[
'urls',
{
type: 'array',
required: true
}
],
[
'current',
{
type: 'string',
required: false
}
]
]);
const PreviewImageApiOptions: ApiOptions<PreviewImageOptions> = {
formatArgs: new Map<string, Function>([
[
'urls',
(urls: string[], params: PreviewImageOptions)=>{
params.urls = urls.map((url)=>getRealPath2(url) as string);
}
]
])
};
const API_CLOSE_PREVIEW_IMAGE = 'closePreviewImage';
const API_SAVE_IMAGE_TO_PHOTOS_ALBUM = 'saveImageToPhotosAlbum';
const SaveImageToPhotosAlbumApiProtocol = new Map<string, ProtocolOptions>([
[
'filePath',
{
type: 'string',
required: true
}
]
]);
const API_SAVE_VIDEO_TO_PHOTOS_ALBUM = 'saveVideoToPhotosAlbum';
const SaveVideoToPhotosAlbumApiProtocol = new Map<string, ProtocolOptions>([
[
'filePath',
{
type: 'string',
required: true
}
]
]);
const CompressImageApiOptions: ApiOptions<CompressImageOptions> = {
formatArgs: new Map<string, Function>([
[
'src',
(src: string, params: CompressImageOptions)=>{
if (src) params.src = getRealPath2(src);
}
],
[
'quality',
(quality: number, params: CompressImageOptions)=>{
if (quality == null) {
params.quality = 80;
}
}
]
])
};
const CompressImageApiProtocol = new Map<string, ProtocolOptions>([
[
'src',
{
type: 'string',
required: true
}
],
[
'quality',
{
type: 'number'
}
],
[
'compressedWidth',
{
type: 'number'
}
],
[
'compressedHeight',
{
type: 'number'
}
]
]);
const API_CHOOSE_FILE = 'chooseFile';
const CHOOSE_MEDIA_TYPE: string[] = [
'all',
'image',
'video'
];
const CHOOSE_FILE_SOURCE_TYPE: string[] = [
'album',
'camera'
];
const ChooseFileApiOptions: ApiOptions<ChooseFileOptions> = {
formatArgs: new Map<string, Function>([
[
'count',
(count: number, params: ChooseFileOptions)=>{
if (!count || count <= 0) {
params.count = 100;
}
return undefined;
}
],
[
'sourceType',
(sourceType: string[] = [], params: ChooseFileOptions)=>{
sourceType = sourceType.filter((type)=>CHOOSE_FILE_SOURCE_TYPE.includes(type));
if (!sourceType.length) {
params.sourceType = [
'album',
'camera'
];
}
return undefined;
}
],
[
'type',
(type: string = 'all', params: ChooseFileOptions)=>{
if (!CHOOSE_MEDIA_TYPE.includes(type)) {
params.type = 'all';
}
return undefined;
}
],
[
'extension',
(extension: string[], params: ChooseFileOptions)=>{
if (extension instanceof Array && extension.length === 0) {
return 'param extension should not be empty.';
}
if (!extension) params.extension = [
''
];
return undefined;
}
]
])
};
const ChooseFileApiProtocol = new Map<string, ProtocolOptions>([
[
'count',
{
type: 'number'
}
],
[
'sourceType',
{
type: 'array'
}
],
[
'type',
{
'type': 'string'
}
],
[
'extension',
{
type: 'array'
}
]
]);
const API_COMPRESS_VIDEO = 'compressVideo';
const CompressVideoApiOptions: ApiOptions<CompressVideoOptions> = {
formatArgs: new Map<string, Function>([
[
'src',
(src: string, params: CompressVideoOptions)=>{
if (src) params.src = getRealPath2(src);
}
]
])
};
const CompressVideoApiProtocol = new Map<string, ProtocolOptions>([
[
'src',
{
type: 'string',
required: true
}
],
[
'quality',
{
type: 'string'
}
],
[
'bitrate',
{
type: 'number'
}
],
[
'fps',
{
type: 'number'
}
],
[
'resolution',
{
type: 'number'
}
]
]);
const getFileName = (path: string)=>{
const array = path.split('/');
return array[array.length - 1];
};
let id: number = 0;
const _compressImage = (args: CompressImageOptions)=>{
const imageName = getFileName(args.src);
const imageExt = imageName.split('.').slice(-1)[0];
const imagePacker: image.ImagePacker = image.createImagePacker();
const file2 = fileIo4.openSync(args.src, fileIo4.OpenMode.READ_ONLY);
if (!file2) {
throw new Error('open file failed');
}
const imageSource: image.ImageSource = image.createImageSource(file2.fd);
if (imageSource == null) {
throw new Error('create image source failed');
}
let decodingOptions: image.DecodingOptions = {
editable: true
};
if (args.rotate != null) {
decodingOptions.rotate = args.rotate;
}
if (args.compressedHeight != null || args.compressedWidth != null) {
decodingOptions.desiredSize = {
height: (args.compressedHeight ?? args.compressedWidth)!,
width: (args.compressedWidth ?? args.compressedHeight)!
};
}
const pixelMap = imageSource.createPixelMapSync(decodingOptions);
let format: string = '';
if ([
'jpg',
'jpe',
'jpeg',
'png'
].includes(imageExt)) {
format = 'image/jpeg';
}
if (imageExt === 'webp') format = 'image/webp';
if (!format.length) {
throw new Error('error image format');
}
const packOptions: image.PackingOption = {
format,
quality: args.quality ?? 80
};
const tempFileName = `${Date.now()}_${id++}.${imageExt}`;
const tempDirPath = `${getEnv4().TEMP_PATH}/compress`;
if (!fileIo4.accessSync(tempDirPath)) {
fileIo4.mkdirSync(tempDirPath, true);
}
const tempFilePath: string = `${tempDirPath}/${tempFileName}`;
const file = fileIo4.openSync(tempFilePath, fileIo4.OpenMode.CREATE | fileIo4.OpenMode.READ_WRITE);
return imagePacker.packToFile(pixelMap, file.fd, packOptions).then((_)=>{
const size = fileIo4.statSync(file.fd).size;
fileIo4.closeSync(file.fd);
pixelMap.release();
return {
size,
tempFilePath
} as _CompressImageSuccess;
});
};
const compressImage: CompressImage = defineAsyncApi<CompressImageOptions, CompressImageSuccess>(API_CHOOSE_IMAGE, (args: CompressImageOptions, executor: ApiExecutor<CompressImageSuccess>)=>{
try {
_compressImage(args).then((res)=>{
executor.resolve({
tempFilePath: res.tempFilePath
} as CompressImageSuccess);
});
} catch (error) {
executor.reject((error as BusinessError11).message);
}
}, CompressImageApiProtocol, CompressImageApiOptions) as CompressImage;
const _getVideoInfo1 = async (uri: string): Promise<GetVideoInfoSuccess> =>{
const file = await fs4.open(uri, fs4.OpenMode.READ_ONLY);
const avMetadataExtractor = await media4.createAVMetadataExtractor();
let metadata: media4.AVMetadata | null = null;
let size: number = 0;
try {
size = (await fs4.stat(file.fd)).size;
avMetadataExtractor.dataSrc = {
fileSize: size,
callback: (buffer: ArrayBuffer, length: number, pos: number | null = null)=>{
return fs4.readSync(file.fd, buffer, {
offset: pos,
length
} as ReadOptions2);
}
};
metadata = await avMetadataExtractor.fetchMetadata();
} catch (error) {
throw error as Error;
} finally{
await avMetadataExtractor.release();
await fs4.close(file);
}
const videoOrientationArr = [
'up',
'right',
'down',
'left'
] as MediaOrientation[];
return {
size: size,
duration: metadata.duration ? Number(metadata.duration) / 1000 : undefined,
width: metadata.videoWidth ? Number(metadata.videoWidth) : undefined,
height: metadata.videoHeight ? Number(metadata.videoHeight) : undefined,
type: metadata.mimeType,
orientation: metadata.videoOrientation ? videoOrientationArr[Number(metadata.videoOrientation) / 90] : undefined
} as GetVideoInfoSuccess;
};
const _getImageInfo = async (uri: string): Promise<GetImageInfoSuccess> =>{
const file = await fs4.open(uri, fs4.OpenMode.READ_ONLY);
const imageSource = image1.createImageSource(file.fd);
const imageInfo = await imageSource.getImageInfo();
let orientation: string = '';
try {
orientation = await imageSource.getImageProperty(image1.PropertyKey.ORIENTATION);
} catch (error) {}
await imageSource.release();
await fs4.close(file.fd);
let orientationNum = 0;
if (typeof orientation === 'string') {
const matched = orientation.match(/^Unknown value (\d)$/);
if (matched && matched[1]) {
orientationNum = Number(matched[1]);
} else if (/^\d$/.test(orientation)) {
orientationNum = Number(orientation);
}
} else if (typeof orientation === 'number') {
orientationNum = orientation;
}
let orientationStr: MediaOrientation = 'up';
switch(orientationNum){
case 2:
orientationStr = 'up-mirrored';
break;
case 3:
orientationStr = 'down';
break;
case 4:
orientationStr = 'down-mirrored';
break;
case 5:
orientationStr = 'left-mirrored';
break;
case 6:
orientationStr = 'right';
break;
case 7:
orientationStr = 'right-mirrored';
break;
case 8:
orientationStr = 'left';
break;
case 0:
case 1:
default:
orientationStr = 'up';
break;
}
return {
path: uri,
width: imageInfo.size.width,
height: imageInfo.size.height,
orientation: orientationStr
} as GetImageInfoSuccess;
};
const _chooseMedia1 = async (options: _ChooseMediaOptions): Promise<chooseMediaSuccessCallbackResult> =>{
const photoSelectOptions = new photoAccessHelper2.PhotoSelectOptions();
const mimeType = options.mimeType;
photoSelectOptions.MIMEType = mimeType;
if (mimeType === photoAccessHelper2.PhotoViewMIMETypes.VIDEO_TYPE) {
photoSelectOptions.maxSelectNumber = 1;
} else {
photoSelectOptions.maxSelectNumber = options.count || 9;
}
photoSelectOptions.isOriginalSupported = options.isOriginalSupported;
photoSelectOptions.isPhotoTakingSupported = !(options.sourceType && !options.sourceType.includes('camera'));
const photoPicker = new photoAccessHelper2.PhotoViewPicker();
const photoSelectResult = await photoPicker.select(photoSelectOptions);
const uris = photoSelectResult.photoUris;
if (mimeType !== photoAccessHelper2.PhotoViewMIMETypes.VIDEO_TYPE) {
let realUris: string[] = uris;
if (!photoSelectResult.isOriginalPhoto) {
const compressResult = await Promise.all(uris.map((uri): Promise<CompressImageSuccess> =>{
return _compressImage({
src: uri,
quality: 80
} as CompressImageOptions);
}));
realUris = compressResult.map((result)=>result.tempFilePath);
}
return {
tempFiles: realUris.map((uri)=>{
const file = fs4.openSync(uri, fs4.OpenMode.READ_ONLY);
const stat = fs4.statSync(file.fd);
fs4.closeSync(file);
return {
fileType: 'image',
tempFilePath: uri,
size: stat.size
} as MediaFile;
})
};
}
const tempFiles: MediaFile[] = [];
for(let i = 0; i < uris.length; i++){
const uri = uris[i];
const videoInfo = await _getVideoInfo1(uri);
tempFiles.push({
fileType: 'video',
tempFilePath: uri,
size: videoInfo.size,
duration: videoInfo.duration,
width: videoInfo.width,
height: videoInfo.height
} as MediaFile);
}
return {
tempFiles
} as chooseMediaSuccessCallbackResult;
};
const getMimeTypeFromExtension = (extension: string): string | null =>{
const typeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension('.' + extension);
const typeObj = uniformTypeDescriptor.getTypeDescriptor(typeId);
const mimeTypes = typeObj.mimeTypes;
return mimeTypes[0] || null;
};
const MediaUniErrors: Map<number, string> = new Map([
[
1101001,
'user cancel'
],
[
1101002,
'fail parameter error: parameter.urls should have at least 1 item'
],
[
1101003,
"file not find"
],
[
1101004,
"Failed to load resource"
],
[
1101005,
"No Permission"
],
[
1101006,
"save error"
],
[
1101007,
"crop error"
],
[
1101008,
'camera error'
],
[
1101009,
"image output failed"
],
[
1101010,
"unexpect error:"
]
]);
const getHMCameraPosition1 = (cameraType: CameraPosition1)=>{
switch(cameraType){
case 'back':
return camera1.CameraPosition.CAMERA_POSITION_BACK;
case 'front':
return camera1.CameraPosition.CAMERA_POSITION_FRONT;
default:
return camera1.CameraPosition.CAMERA_POSITION_BACK;
}
};
const takePhoto = async (cameraType: CameraPosition1 = 'back')=>{
let pickerProfile: cameraPicker1.PickerProfile = {
cameraPosition: getHMCameraPosition1(cameraType)
};
const res = await cameraPicker1.pick(UTSHarmony.getUIAbilityContext()!, [
cameraPicker1.PickerMediaType.PHOTO
], pickerProfile);
const file = fs5.openSync(res.resultUri, fs5.OpenMode.READ_ONLY);
const stat = fs5.statSync(file.fd);
return {
tempFiles: [
{
tempFilePath: res.resultUri,
size: stat.size
}
]
} as TakePhotoRes;
};
const takeVideo = async (args: TakeVideoOptions | null = null)=>{
let pickerProfile: cameraPicker1.PickerProfile = {
cameraPosition: getHMCameraPosition1(args?.cameraType ?? 'back'),
videoDuration: args?.videoDuration
};
const res = await cameraPicker1.pick(UTSHarmony.getUIAbilityContext()!, [
cameraPicker1.PickerMediaType.VIDEO
], pickerProfile);
return _getVideoInfo1(res.resultUri).then((getVideInfoRes)=>{
return {
path: res.resultUri,
size: getVideInfoRes.size,
duration: getVideInfoRes.duration!,
width: getVideInfoRes.width!,
height: getVideInfoRes.height!,
type: getVideInfoRes.type!,
orientation: getVideInfoRes.orientation!
} as TakeVideoRes;
});
};
const errSubject = 'uni-chooseImage';
const _chooseImage = (options: ChooseImageOptions, res: ApiExecutor<ChooseImageSuccess>)=>{
_chooseMedia1({
mimeType: photoAccessHelper3.PhotoViewMIMETypes.IMAGE_TYPE,
sourceType: [
"album"
],
isOriginalSupported: options.sizeType?.includes('original') !== false,
count: options.count!
} as _ChooseMediaOptions).then((chooseMediaRes)=>{
const tempFiles = chooseMediaRes.tempFiles;
if (tempFiles.length === 0) {
const errMsg = MediaUniErrors.get(1101001) as string;
res.reject(errMsg, {
errCode: 1101001
} as ApiError);
return;
}
res.resolve({
errMsg: '',
errSubject,
tempFilePaths: chooseMediaRes.tempFiles.map((file)=>file.tempFilePath),
tempFiles: chooseMediaRes.tempFiles.map((file)=>{
return {
path: file.tempFilePath,
size: file.size
} as ChooseImageTempFile;
})
} as ChooseImageSuccess);
}, (err: Error)=>{
res.reject(err.message);
});
};
const _takePhoto = (options: ChooseImageOptions, res: ApiExecutor<ChooseImageSuccess>)=>{
takePhoto().then((photo)=>{
res.resolve({
errMsg: '',
errSubject,
tempFilePaths: photo.tempFiles.map((file)=>file.tempFilePath),
tempFiles: photo.tempFiles.map((tempFile): ChooseImageTempFile =>({
path: tempFile.tempFilePath,
size: tempFile.size
} as ChooseImageTempFile))
} as ChooseImageSuccess);
}).catch((err: Error)=>{
res.reject(err.message);
});
};
const chooseImage: ChooseImage = defineAsyncApi<ChooseImageOptions, ChooseImageSuccess>(API_CHOOSE_IMAGE, async (options: ChooseImageOptions, res: ApiExecutor<ChooseImageSuccess>)=>{
if (options.sourceType?.length === 1 && options.sourceType[0] === 'camera') {
_takePhoto(options, res);
} else if (options.sourceType?.length === 1 && options.sourceType[0] === 'album') {
_chooseImage(options, res);
} else {
const lastWindow = UTSHarmony.getCurrentWindow() as window1.Window;
const UIContextPromptAction = await lastWindow.getUIContext().getPromptAction();
UIContextPromptAction.showActionMenu({
buttons: [
{
text: '拍照',
color: '#000000'
},
{
text: '从相册选择',
color: '#000000'
}
]
} as promptAction2.ActionMenuOptions, (err, ref)=>{
let index = ref.index;
if (err) {
res.reject('cancel');
} else {
if (index === 0) {
_takePhoto(options, res);
} else if (index === 1) {
_chooseImage(options, res);
}
}
});
}
}, ChooseImageApiProtocol, ChooseImageApiOptions) as ChooseImage;
const _chooseVideo = (options: ChooseVideoOptions, res: ApiExecutor<ChooseVideoSuccess>)=>{
_chooseMedia1({
mimeType: photoAccessHelper4.PhotoViewMIMETypes.VIDEO_TYPE,
sourceType: [
"album"
],
isOriginalSupported: options.compressed === false
} as _ChooseMediaOptions).then((chooseMediaRes)=>{
const file = chooseMediaRes.tempFiles[0];
if (!file) {
const errMsg = MediaUniErrors.get(1101001) as string;
res.reject(errMsg, {
errCode: 1101001
} as ApiError);
return;
}
res.resolve({
tempFilePath: file.tempFilePath,
duration: file.duration,
size: file.size,
width: file.width,
height: file.height
} as ChooseVideoSuccess);
}, (err: Error)=>{
res.reject(err.message);
});
};
const _takeVideo = (options: ChooseVideoOptions, res: ApiExecutor<ChooseVideoSuccess>)=>{
const takeVideoOptions: TakeVideoOptions = {
cameraType: options.camera! as CameraPosition1,
videoDuration: options.maxDuration!
};
takeVideo(takeVideoOptions).then((video)=>{
res.resolve({
tempFilePath: video.path,
duration: video.duration,
size: video.size,
width: video.width,
height: video.height
} as ChooseVideoSuccess);
}).catch((err: Error)=>{
res.reject(err.message);
});
};
const chooseVideo: ChooseVideo = defineAsyncApi<ChooseVideoOptions, ChooseVideoSuccess>(API_CHOOSE_VIDEO, async (options: ChooseVideoOptions, res: ApiExecutor<ChooseVideoSuccess>)=>{
if (options.sourceType?.length === 1 && options.sourceType[0] === 'camera') {
_takeVideo(options, res);
} else if (options.sourceType?.length === 1 && options.sourceType[0] === 'album') {
_chooseVideo(options, res);
} else {
const lastWindow = UTSHarmony.getCurrentWindow() as window2.Window;
const UIContextPromptAction = await lastWindow.getUIContext().getPromptAction();
UIContextPromptAction.showActionMenu({
buttons: [
{
text: '拍摄',
color: '#000000'
},
{
text: '从相册选择',
color: '#000000'
}
]
} as promptAction3.ActionMenuOptions, (err, ref)=>{
let index = ref.index;
if (err) {
res.reject('cancel');
} else {
if (index === 0) {
_takeVideo(options, res);
} else if (index === 1) {
_chooseVideo(options, res);
}
}
});
}
}, ChooseVideoApiProtocol, ChooseVideoApiOptions) as ChooseVideo;
const getImageInfo: GetImageInfo = defineAsyncApi<GetImageInfoOptions, GetImageInfoSuccess>(API_GET_IMAGE_INFO, async (options: GetImageInfoOptions, res: ApiExecutor<GetImageInfoSuccess>)=>{
let src = options.src;
if (src.startsWith('http:') || src.startsWith('https:')) {
try {
src = await new Promise<string>((resolve, reject)=>{
uni.downloadFile({
url: options.src,
success: (res: IGetImageInfoDownloadSuccess)=>{
resolve(res.tempFilePath);
},
fail: (err: IGetImageInfoDownloadFail)=>{
reject(err);
}
} as IGetImageInfoDownloadOptions);
});
} catch (err) {
const error = err as IGetImageInfoDownloadFail;
res.reject(error.errMsg);
return;
}
}
_getImageInfo(src).then((getImageInfoRes)=>{
res.resolve(getImageInfoRes);
}, (err: Error)=>{
res.reject(err.message);
});
}, GetImageInfoApiProtocol, GetImageInfoApiOptions) as GetImageInfo;
const getVideoInfo: GetVideoInfo = defineAsyncApi<GetVideoInfoOptions, GetVideoInfoSuccess>(API_GET_VIDEO_INFO, (options: GetVideoInfoOptions, res: ApiExecutor<GetVideoInfoSuccess>)=>{
_getVideoInfo1(options.src).then((getVideInfoRes)=>{
res.resolve({
size: getVideInfoRes.size,
duration: getVideInfoRes.duration!,
width: getVideInfoRes.width!,
height: getVideInfoRes.height!,
type: getVideInfoRes.type!,
orientation: getVideInfoRes.orientation!
} as GetVideoInfoSuccess);
}, (err: Error)=>{
res.reject(err.message);
});
}, GetVideoInfoApiProtocol, GetVideoInfoApiOptions) as GetVideoInfo;
const previewImage: PreviewImage = defineAsyncApi<PreviewImageOptions, PreviewImageSuccess>(API_PREVIEW_IMAGE, (options: PreviewImageOptions, exec: ApiExecutor<PreviewImageSuccess>)=>{
const currentUrl = typeof options.current === 'number' ? options.urls[options.current ?? 0] : options.current as string;
onNativePageReady1().then((nativePage: Object)=>{
getOSRuntime().previewImage({
urls: options.urls.map((url)=>getRealPath3(url) as string),
current: getRealPath3(currentUrl || ''),
showmenu: options.showmenu === false ? false : true
} as IPreviewImageOptions, nativePage);
exec.resolve({
errSubject: 'uni-previewImage',
errMsg: ''
} as PreviewImageSuccess);
});
}, PreviewImageApiProtocol, PreviewImageApiOptions) as PreviewImage;
const closePreviewImage: ClosePreviewImage = defineAsyncApi<ClosePreviewImageOptions, ClosePreviewImageSuccess>(API_CLOSE_PREVIEW_IMAGE, (options: ClosePreviewImageOptions, exec: ApiExecutor<ClosePreviewImageSuccess>)=>{
onNativePageReady1().then((nativePage: Object)=>{
getOSRuntime().closePreviewImage();
exec.resolve({
errMsg: ''
} as ClosePreviewImageSuccess);
});
}) as ClosePreviewImage;
const saveResource = async (src: Resource, dest: string)=>{
const context = UTSHarmony.getUIAbilityContext() as common.UIAbilityContext;
const resourceManager = context.resourceManager;
const srcPath: string = src.params?.[0] as string;
const destFile = fs6.openSync(dest, fs6.OpenMode.WRITE_ONLY);
const content = await resourceManager.getRawFileContent(srcPath);
await fs6.write(destFile.fd, content.buffer as ArrayBuffer);
await fs6.close(destFile);
};
const saveUri = async (src: string, dest: string)=>{
const srcFile = fs6.openSync(src, fs6.OpenMode.READ_ONLY);
const destFile = fs6.openSync(dest, fs6.OpenMode.WRITE_ONLY);
await fs6.copyFile(srcFile.fd, destFile.fd);
await fs6.close(srcFile);
await fs6.close(destFile);
};
const saveMediaToAlbum = async (fromUri: string, type: 'image' | 'video'): Promise<string | ISaveMediaError> =>{
const realPath = getResourceStr(fromUri) as string | Resource;
const context = UTSHarmony.getUIAbilityContext() as common.UIAbilityContext;
let fileName = Date.now() + (type === 'image' ? '.png' : '.mp4');
const isResource = typeof realPath !== 'string';
if (isResource) {
if (typeof realPath.params?.[0] === 'string') {
fileName = realPath.params?.[0].split('/').pop() || fileName;
}
} else {
fileName = realPath.split('/').pop() || fileName;
}
const phAccessHelper = photoAccessHelper5.getPhotoAccessHelper(context);
const fileNameParts = fileName.split('.');
const title = fileNameParts[0];
const fileNameExtension = fileNameParts.pop()!;
const photoCreationConfigs: Array<photoAccessHelper5.PhotoCreationConfig> = [
{
title,
fileNameExtension,
photoType: type === 'image' ? photoAccessHelper5.PhotoType.IMAGE : photoAccessHelper5.PhotoType.VIDEO
}
];
const desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog([
fromUri.startsWith('file://') ? fromUri : fileUri.getUriFromPath(fromUri)
], photoCreationConfigs);
if (!desFileUris || desFileUris.length === 0) {
return {
code: 1101001,
message: MediaUniErrors.get(1101001) as string
} as ISaveMediaError;
}
const destUri = desFileUris[0];
if (!destUri.startsWith('file://')) {
return {
code: 1101006,
message: MediaUniErrors.get(1101006) as string + ', code: ' + destUri
} as ISaveMediaError;
}
if (isResource) {
await saveResource(realPath as Resource, destUri);
} else {
await saveUri(realPath as string, destUri);
}
return destUri;
};
const saveImageToPhotosAlbum: SaveImageToPhotosAlbum = defineAsyncApi<SaveImageToPhotosAlbumOptions, SaveImageToPhotosAlbumSuccess>(API_SAVE_IMAGE_TO_PHOTOS_ALBUM, (options: SaveImageToPhotosAlbumOptions, res: ApiExecutor<SaveImageToPhotosAlbumSuccess>)=>{
saveMediaToAlbum(options.filePath, 'image').then((uri)=>{
if (typeof uri === 'object') {
const err = uri as ISaveMediaError;
res.reject(err.message, {
errCode: err.code
} as ApiError);
return;
}
res.resolve({
path: uri
} as SaveImageToPhotosAlbumSuccess);
}, (err: Error)=>{
res.reject(err.message);
});
}, SaveImageToPhotosAlbumApiProtocol) as SaveImageToPhotosAlbum;
const saveVideoToPhotosAlbum: SaveVideoToPhotosAlbum = defineAsyncApi<SaveVideoToPhotosAlbumOptions, SaveVideoToPhotosAlbumSuccess>(API_SAVE_VIDEO_TO_PHOTOS_ALBUM, (options: SaveVideoToPhotosAlbumOptions, res: ApiExecutor<SaveVideoToPhotosAlbumSuccess>)=>{
saveMediaToAlbum(options.filePath, 'video').then((uri)=>{
if (typeof uri === 'object') {
const err = uri as ISaveMediaError;
res.reject(err.message, {
errCode: err.code
} as ApiError);
return;
}
res.resolve({} as SaveVideoToPhotosAlbumSuccess);
}, (err: Error)=>{
res.reject(err.message);
});
}, SaveVideoToPhotosAlbumApiProtocol) as SaveVideoToPhotosAlbum;
const IMAGES: string[] = [
"jpg",
"jpe",
"pbm",
"pgm",
"pnm",
"ppm",
"psd",
"pic",
"rgb",
"svg",
"svgz",
"tif",
"xif",
"wbmp",
"wdp",
"xbm",
"ico"
];
const VIDEOS: string[] = [
"3g2",
"3gp",
"avi",
"f4v",
"flv",
"jpgm",
"jpgv",
"m1v",
"m2v",
"mpe",
"mpg",
"mpg4",
"m4v",
"mkv",
"mov",
"qt",
"movie",
"mp4v",
"ogv",
"smv",
"wm",
"wmv",
"wmx",
"wvx"
];
const getFile = (url: string)=>{
const file = fileIo5.openSync(url, fileIo5.OpenMode.READ_ONLY);
const size = fileIo5.statSync(file.fd).size;
const ext = file.name.split('.').pop()!;
return {
path: url,
name: file.name,
size,
type: getMimeTypeFromExtension(ext) ?? ext
} as ChooseFileTempFile;
};
const chooseFile: ChooseFile = defineAsyncApi<ChooseFileOptions, ChooseFileSuccess>(API_CHOOSE_FILE, (args: ChooseFileOptions, executor: ApiExecutor<ChooseFileSuccess>)=>{
if ([
'image',
'video'
].includes(args.type ?? '')) {
if (args.type === 'image') {
chooseImage({
sourceType: args.sourceType,
success (res: ChooseImageSuccess) {
executor.resolve({
tempFilePaths: res.tempFilePaths,
tempFiles: res.tempFilePaths.map((url): ChooseFileTempFile =>getFile(url))
} as ChooseFileSuccess);
},
fail (err: IMediaError) {
executor.reject(err.errMsg, {
errCode: err.errCode
} as ApiError);
}
} as ChooseImageOptions);
}
if (args.type === 'video') {
chooseVideo({
sourceType: args.sourceType,
success (res: ChooseVideoSuccess) {
executor.resolve({
tempFilePaths: [
res.tempFilePath
],
tempFiles: [
getFile(res.tempFilePath)
]
} as ChooseFileSuccess);
},
fail (err: IMediaError) {
executor.reject(err.errMsg, {
errCode: err.errCode
} as ApiError);
}
} as ChooseVideoOptions);
}
} else {
try {
let documentSelectOptions = new picker.DocumentSelectOptions();
let documentPicker = new picker.DocumentViewPicker(UTSHarmony.getUIAbilityContext()!);
documentSelectOptions.selectMode = picker.DocumentSelectMode.FILE;
if (args.count) documentSelectOptions.maxSelectNumber = args.count;
if (args.extension) documentSelectOptions.fileSuffixFilters = args.extension;
if (args.type === 'image') {
documentSelectOptions.fileSuffixFilters = documentSelectOptions.fileSuffixFilters?.concat(IMAGES);
}
if (args.type === 'video') {
documentSelectOptions.fileSuffixFilters = documentSelectOptions.fileSuffixFilters?.concat(VIDEOS);
}
documentPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>)=>{
let tempFiles = documentSelectResult.map((url): ChooseFileTempFile =>getFile(url));
if (tempFiles.length !== 0) {
executor.resolve({
tempFilePaths: documentSelectResult,
tempFiles
} as ChooseFileSuccess);
} else {
executor.reject('cancel');
}
}).catch((err: BusinessError12)=>{
executor.reject(err.message, {
errCode: err.code
} as ApiError);
});
} catch (error) {
let err: BusinessError12 = error as BusinessError12;
executor.reject(err.message, {
errCode: err.code
} as ApiError);
}
}
}, ChooseFileApiProtocol, ChooseFileApiOptions) as ChooseFile;
const getQuality = (quality: string | null = null)=>{
switch(quality){
case "low":
return CompressQuality.COMPRESS_QUALITY_LOW;
case 'medium':
return CompressQuality.COMPRESS_QUALITY_MEDIUM;
}
return CompressQuality.COMPRESS_QUALITY_HIGH;
};
const compressVideo: CompressVideo = defineAsyncApi<CompressVideoOptions, CompressVideoSuccess>(API_COMPRESS_VIDEO, async (args: CompressVideoOptions, executor: ApiExecutor<CompressVideoSuccess>)=>{
let videoCompressor = new VideoCompressor();
videoCompressor.compressVideo(UTSHarmony.getUIAbilityContext()!, args.src, getQuality(args.quality!)).then((data: CompressorResponse): void =>{
if (data.code == CompressorResponseCode.SUCCESS) {
_getVideoInfo1(data.outputPath).then((res)=>{
executor.resolve({
tempFilePath: data.outputPath,
size: res.size
} as CompressVideoSuccess);
});
} else {
executor.reject(data.message, {
errCode: data.code
} as ApiError);
}
}).catch((err: Error)=>{
executor.reject(err.message);
});
}, CompressVideoApiProtocol, CompressVideoApiOptions) as CompressVideo;
const API_REQUEST = 'request';
const RequestApiProtocol = new Map<string, ProtocolOptions>([
[
'url',
{
type: 'string',
required: true
}
],
[
'data',
{
type: 'object',
required: false
}
],
[
'header',
{
type: 'object',
required: false
}
],
[
'method',
{
type: 'string',
required: false
}
],
[
'dataType',
{
type: 'string',
required: false
}
],
[
'responseType',
{
type: 'string',
required: false
}
],
[
'timeout',
{
type: 'number',
required: false
}
],
[
'sslVerify',
{
type: 'boolean',
required: false
}
],
[
'withCredentials',
{
type: 'boolean',
required: false
}
],
[
'firstIpv4',
{
type: 'boolean',
required: false
}
]
]);
const RequestApiOptions: ApiOptions<RequestOptions<Object>> = {
formatArgs: new Map<string, Function>([
[
'url',
(url: string, params: RequestOptions<Object>)=>{
if (url == null) {
throw new Error('url is required');
}
}
],
[
'method',
(method: string, params: RequestOptions<Object>)=>{
params.method = (method || 'GET').toUpperCase() as RequestMethod;
}
],
[
'dataType',
(dataType: string, params: RequestOptions<Object>)=>{
if (dataType == null) {
params.dataType = 'json';
}
}
],
[
'responseType',
(responseType: string, params: RequestOptions<Object>)=>{
if (responseType == null) {
params.responseType = 'text';
}
}
],
[
'timeout',
(timeout: number, params: RequestOptions<Object>)=>{
if (timeout == null) {
params.timeout = 60000;
}
}
],
[
'sslVerify',
(sslVerify: boolean, params: RequestOptions<Object>)=>{
if (sslVerify == null) {
params.sslVerify = true;
}
}
],
[
'withCredentials',
(withCredentials: boolean, params: RequestOptions<Object>)=>{
if (withCredentials == null) {
params.withCredentials = false;
}
}
],
[
'firstIpv4',
(firstIpv4: boolean, params: RequestOptions<Object>)=>{
if (firstIpv4 == null) {
params.firstIpv4 = false;
}
}
]
])
};
const API_DOWNLOAD_FILE = 'downloadFile';
const DownloadFileApiProtocol = new Map<string, ProtocolOptions>([
[
'url',
{
type: 'string',
required: true
}
],
[
'header',
{
type: 'object',
required: false
}
],
[
'timeout',
{
type: 'number',
required: false
}
]
]);
const DownloadFileApiOptions: ApiOptions<DownloadFileOptions> = {
formatArgs: new Map<string, Function>([
[
'url',
(url: string, params: DownloadFileOptions)=>{
if (url == null) {
throw new Error('url is required');
}
}
]
])
};
const API_UPLOAD_FILE = 'uploadFile';
const UploadFileApiProtocol = new Map<string, ProtocolOptions>([
[
'url',
{
type: 'string',
required: true
}
],
[
'filePath',
{
type: 'string',
required: false
}
],
[
'name',
{
type: 'string',
required: false
}
],
[
'header',
{
type: 'object',
required: false
}
],
[
'formData',
{
type: 'object',
required: false
}
],
[
'timeout',
{
type: 'number',
required: false
}
]
]);
const UploadFileApiOptions: ApiOptions<UploadFileOptions> = {
formatArgs: new Map<string, Function>([
[
'url',
(url: string, params: UploadFileOptions)=>{
if (url == null) {
throw new Error('url is required');
}
}
],
[
'name',
(name: string, params: UploadFileOptions)=>{
if (name == null) {
params.name = 'file';
}
}
]
])
};
const API_CONFIG_MTLS = 'configMTLS';
const ConfigMTLSApiProtocol = new Map<string, ProtocolOptions>([
[
'certificates',
{
type: 'array',
required: true
}
]
]);
const ConfigMTLSApiOptions: ApiOptions<ConfigMTLSOptions> = {
formatArgs: new Map<string, Function>([
[
'certificates',
(certificates: (Certificate[]) | null = null)=>{
if (!certificates || certificates.some((item)=>typeof item.host !== 'string')) {
return '参数 certificates 配置错误,请确认后重试';
}
return undefined;
}
]
])
};
const needsEncoding = (str: string)=>{
const decoded = decodeURIComponent(str);
if (decoded !== str) {
if (encodeURIComponent(decoded) === str) {
return false;
}
}
return encodeURIComponent(decoded) !== decoded;
};
const parseUrl = (url: string)=>{
try {
const urlObj = harmonyUrl.URL.parseURL(url);
urlObj.params.forEach((value, key)=>{
if (needsEncoding(value)) {
urlObj.params.set(key, value);
}
});
return urlObj.toString();
} catch (error) {
return url;
}
};
const certificates: Certificate[] = [];
const getCertType = (certPath: string): http.CertType =>{
const certExt = certPath.split('.').pop();
switch(certExt){
case 'p12':
return http.CertType.P12;
case 'pem':
return http.CertType.PEM;
default:
return http.CertType.PEM;
}
};
const getClientCertificate = (url: string): http.ClientCert | undefined =>{
if (certificates.length === 0) return undefined;
const urlObj = harmonyUrl.URL.parseURL(url);
const cert = certificates.find((certificate)=>certificate.host === urlObj.host);
if (cert) {
return {
certType: getCertType(cert.client!),
certPath: getRealPath4(cert.client!),
keyPath: cert.keyPath ?? '',
keyPassword: cert.clientPassword
} as http.ClientCert;
}
return undefined;
};
const replaceHttpWithHttps = (url: string): string =>{
return url.replace(/^http:/, 'https:');
};
const getCookieSync = (url: string): string =>{
return webview.WebCookieManager.fetchCookieSync(replaceHttpWithHttps(url));
};
const setCookieSync = (url: string, cookies: string[]): void =>{
cookies.forEach((cookie)=>{
let hasSecure = false;
let hasSameSite = false;
let savedCookie = cookie.split(';').map((cookieItem)=>{
const pair = cookieItem.split('=').map((item)=>item.trim());
const keyLower = pair[0].toLowerCase();
if (keyLower === 'secure') {
hasSecure = true;
return cookieItem;
}
if (keyLower === 'samesite') {
hasSameSite = true;
return 'samesite=none';
}
return cookieItem;
}).join(';');
if (!hasSecure) {
savedCookie += '; secure';
}
if (!hasSameSite) {
savedCookie += '; samesite=none';
}
try {
webview.WebCookieManager.configCookieSync(replaceHttpWithHttps(url), savedCookie);
} catch (error) {}
});
webview.WebCookieManager.saveCookieAsync();
};
const cookiesParse = (header: Record<string, string>)=>{
let cookiesArr: string[] = [];
const handleCookiesArr = (header['Set-Cookie'] || header['set-cookie'] || []) as string[];
for(let i = 0; i < handleCookiesArr.length; i++){
if (handleCookiesArr[i].indexOf('Expires=') !== -1 || handleCookiesArr[i].indexOf('expires=') !== -1) {
cookiesArr.push(handleCookiesArr[i].replace(',', ''));
} else {
cookiesArr.push(handleCookiesArr[i]);
}
}
return cookiesArr;
};
class RequestTask1 implements RequestTask {
__v_skip: boolean = true;
private _requestTask: IRequestTask;
constructor(requestTask: IRequestTask){
this._requestTask = requestTask;
}
abort() {
this._requestTask.abort();
}
onHeadersReceived(callback: Function) {
this._requestTask.onHeadersReceived(callback);
}
offHeadersReceived(callback: Function | null = null) {
this._requestTask.offHeadersReceived(callback);
}
}
const request = defineTaskApi<RequestOptions<Object>, RequestSuccess<Object>, RequestTask>(API_REQUEST, (args: RequestOptions<Object>, exec: ApiExecutor<RequestSuccess<Object>>)=>{
let header = args.header, method = args.method, data = args.data, dataType = args.dataType, timeout = args.timeout, url = args.url, responseType = args.responseType;
header = header || {} as ESObject;
if (!header!['Cookie'] && !header!['cookie']) {
header!['Cookie'] = getCookieSync(url);
}
let contentType = '';
const headers = {} as Record<string, Object>;
const headerRecord = header as Object as Record<string, string>;
const headerKeys = Object.keys(headerRecord);
for(let i = 0; i < headerKeys.length; i++){
const name = headerKeys[i];
if (name.toLowerCase() === 'content-type') {
contentType = headerRecord[name] as string;
}
headers[name.toLowerCase()] = headerRecord[name];
}
if (!contentType && method === 'POST') {
headers['Content-Type'] = 'application/json';
contentType = 'application/json';
}
if (method === 'GET' && data) {
const dataRecord = data as Record<string, Object>;
const query = Object.keys(dataRecord).map((key)=>{
return (encodeURIComponent(key) + '=' + encodeURIComponent(dataRecord[key] as string | number | boolean));
}).join('&');
url += query ? (url.indexOf('?') > -1 ? '&' : '?') + query : '';
data = null;
} else if (method !== 'GET' && contentType && contentType.indexOf('application/json') === 0 && data) {
data = JSON.stringify(data);
} else if (method !== 'GET' && contentType && contentType.indexOf('application/x-www-form-urlencoded') === 0 && data) {
const dataRecord = data as Record<string, Object>;
data = Object.keys(dataRecord).map((key)=>{
return (encodeURIComponent(key) + '=' + encodeURIComponent(dataRecord[key] as number | string | boolean));
}).join('&');
}
const httpRequest = http1.createHttp();
const mp = getCurrentMP1();
const userAgent = mp.userAgent.fullUserAgent;
if (userAgent && headers && !headers!['User-Agent'] && !headers!['user-agent']) {
headers!['User-Agent'] = userAgent;
}
const emitter = new Emitter2() as IUniRequestEmitter;
const requestTask: IRequestTask = {
abort () {
emitter.off('headersReceive');
httpRequest.destroy();
},
onHeadersReceived (callback: Function) {
emitter.on('headersReceive', callback);
},
offHeadersReceived (callback: Function | null = null) {
emitter.off('headersReceive', callback);
}
};
const destroy = ()=>{
emitter.off('headersReceive');
httpRequest.destroy();
};
mp.on('beforeClose', destroy);
let latestHeaders: Object | null = null;
let lastUrl = url;
httpRequest.on('headersReceive', (headers: Object)=>{
const realHeaders = headers as Record<string, string | string[]>;
const setCookieHeader = realHeaders['set-cookie'] || realHeaders['Set-Cookie'];
if (setCookieHeader) {
setCookieSync(lastUrl, setCookieHeader as string[]);
}
latestHeaders = headers;
const location = realHeaders['location'] || realHeaders['Location'];
if (location) {
lastUrl = location as string;
}
});
const bufs = [] as buffer1.Buffer[];
httpRequest.on('dataReceive', (data)=>{
bufs.push(buffer1.from(data));
});
httpRequest.requestInStream(parseUrl(url), {
header: headers,
method: (method || 'GET').toUpperCase() as http1.RequestMethod,
extraData: data || undefined,
connectTimeout: timeout ? timeout : undefined,
readTimeout: timeout ? timeout : undefined,
clientCert: getClientCertificate(url)
} as http1.HttpRequestOptions, (err, statusCode)=>{
if (err) {
exec.reject(err.message);
} else {
const responseData = buffer1.concat(bufs);
let data: ArrayBuffer | string | object = '';
if (responseType === 'arraybuffer') {
data = responseData.buffer;
} else {
data = responseData.toString('utf8');
if (dataType === 'json') {
try {
data = JSON.parse(data);
} catch (e) {}
}
}
const headers = latestHeaders as Record<string, string | string[]>;
const oldCookies = headers ? (headers['Set-Cookie'] || headers['set-cookie'] || []) as string[] : [] as string[];
const cookies = latestHeaders ? cookiesParse(latestHeaders as Record<string, string>) : [];
let newCookies = oldCookies.join(',');
if (newCookies) {
if (headers['Set-Cookie']) {
headers['Set-Cookie'] = newCookies;
} else {
headers['set-cookie'] = newCookies;
}
}
exec.resolve({
data,
statusCode,
header: latestHeaders!,
cookies: cookies
} as RequestSuccess<Object>);
}
requestTask.offHeadersReceived();
httpRequest.destroy();
mp.off('beforeClose', destroy);
});
return new RequestTask1(requestTask);
}, RequestApiProtocol, RequestApiOptions) as Request<Object>;
const lookupExt = (contentType: string): string | undefined =>{
const rawContentType = contentType.split(';')[0].trim().toLowerCase();
return (UTSHarmony.getExtensionFromMimeType(rawContentType) as string | null) || undefined;
};
const lookupContentTypeWithUri = (uri: string): string | undefined =>{
const uriArr = uri.split('.');
if (uriArr.length <= 1) {
return undefined;
}
const ext = uriArr.pop() as string;
return (UTSHarmony.getMimeTypeFromExtension(ext) as string | null) || undefined;
};
class UploadTask1 implements UploadTask {
__v_skip: boolean = true;
private _uploadTask: IUploadTask;
constructor(uploadTask: IUploadTask){
this._uploadTask = uploadTask;
}
abort() {
this._uploadTask.abort();
}
onProgressUpdate(callback: Function) {
this._uploadTask.onProgressUpdate(callback);
}
offProgressUpdate(callback: Function | null = null) {
this._uploadTask.offProgressUpdate(callback);
}
onHeadersReceived(callback: Function) {
this._uploadTask.onHeadersReceived(callback);
}
offHeadersReceived(callback: Function | null = null) {
this._uploadTask.offHeadersReceived(callback);
}
}
const readFile = (filePath: string): ArrayBuffer =>{
const readFilePath = getRealPath5(filePath) as string;
const file = fs7.openSync(readFilePath, fs7.OpenMode.READ_ONLY);
const stat = fs7.statSync(file.fd);
const data = new ArrayBuffer(stat.size);
fs7.readSync(file.fd, data);
fs7.closeSync(file.fd);
return data;
};
const uploadFile = defineTaskApi<UploadFileOptions, UploadFileSuccess, UploadTask>(API_UPLOAD_FILE, (args: UploadFileOptions, exec: ApiExecutor<UploadFileSuccess>)=>{
let url = args.url, timeout = args.timeout, header = args.header, formData = args.formData, files = args.files, filePath = args.filePath, name = args.name;
header = header || {} as ESObject;
if (!header!['Cookie'] && !header!['cookie']) {
header!['Cookie'] = getCookieSync(url);
}
const headers = {} as Record<string, Object>;
if (header) {
const headerRecord = header as Object as Record<string, string>;
const headerKeys = Object.keys(headerRecord);
for(let i = 0; i < headerKeys.length; i++){
const name = headerKeys[i];
headers[name.toLowerCase()] = headerRecord[name];
}
}
headers['Content-Type'] = 'multipart/form-data';
const multiFormDataList = [] as Array<http2.MultiFormData>;
if (formData) {
const formDataRecord = formData as Object as Record<string, Object>;
const formDataKeys = Object.keys(formDataRecord);
for(let i = 0; i < formDataKeys.length; i++){
const name = formDataKeys[i];
multiFormDataList.push({
name,
contentType: 'text/plain',
data: String(formDataRecord[name])
} as http2.MultiFormData);
}
}
try {
if (files && files.length) {
for(let i = 0; i < files.length; i++){
const _files_i = files[i], name = _files_i.name, uri = _files_i.uri;
multiFormDataList.push({
name: name || 'file',
contentType: lookupContentTypeWithUri(uri) || 'application/octet-stream',
remoteFileName: uri.split('/').pop() || 'no-name',
data: readFile(uri!)
} as http2.MultiFormData);
}
} else if (filePath) {
multiFormDataList.push({
name: name || 'file',
contentType: lookupContentTypeWithUri(filePath!) || 'application/octet-stream',
remoteFileName: filePath.split('/').pop() || 'no-name',
data: readFile(filePath!)
} as http2.MultiFormData);
}
} catch (error) {
exec.reject((error as Error).message);
return new UploadTask1({
abort: ()=>{},
onHeadersReceived: (callback: Function)=>{},
offHeadersReceived: (callback: Function)=>{},
onProgressUpdate: (callback: Function)=>{},
offProgressUpdate: (callback: Function)=>{}
} as IUploadTask);
}
const httpRequest = http2.createHttp();
const mp = getCurrentMP2();
const userAgent = mp.userAgent.fullUserAgent;
if (userAgent && !headers['User-Agent'] && !headers['user-agent']) {
headers['User-Agent'] = userAgent;
}
const emitter = new Emitter3() as IUniUploadFileEmitter;
const uploadTask: IUploadTask = {
abort () {
emitter.off('headersReceive');
emitter.off('progress');
httpRequest.destroy();
},
onHeadersReceived (callback: Function) {
emitter.on('headersReceive', callback);
},
offHeadersReceived (callback: Function | null = null) {
emitter.off('headersReceive', callback);
},
onProgressUpdate (callback: Function) {
emitter.on('progress', callback);
},
offProgressUpdate (callback: Function | null = null) {
emitter.off('progress', callback);
}
};
const destroy = ()=>{
emitter.off('headersReceive');
emitter.off('progress');
httpRequest.destroy();
};
mp.on('beforeClose', destroy);
let lastUrl = url;
httpRequest.on('headersReceive', (headers: Object)=>{
const realHeaders = headers as Record<string, string | string[]>;
const setCookieHeader = realHeaders['set-cookie'] || realHeaders['Set-Cookie'];
if (setCookieHeader) {
setCookieSync(lastUrl, setCookieHeader as string[]);
}
const location = realHeaders['location'] || realHeaders['Location'];
if (location) {
lastUrl = location as string;
}
});
httpRequest.on('dataSendProgress', (ref)=>{
let sendSize = ref.sendSize, totalSize = ref.totalSize;
emitter.emit('progress', {
progress: Math.floor((sendSize / totalSize) * 100),
totalBytesSent: sendSize,
totalBytesExpectedToSend: totalSize
} as OnProgressUpdateResult);
});
httpRequest.request(parseUrl(url), {
header: headers,
method: http2.RequestMethod.POST,
connectTimeout: timeout ? timeout : undefined,
readTimeout: timeout ? timeout : undefined,
multiFormDataList,
expectDataType: http2.HttpDataType.STRING,
clientCert: getClientCertificate(url)
} as http2.HttpRequestOptions, (err, res)=>{
if (err) {
exec.reject(err.message);
} else {
exec.resolve({
data: res.result as string,
statusCode: res.responseCode
} as UploadFileSuccess);
}
uploadTask.offHeadersReceived();
uploadTask.offProgressUpdate();
httpRequest.destroy();
mp.off('beforeClose', destroy);
});
return new UploadTask1(uploadTask);
}, UploadFileApiProtocol, UploadFileApiOptions) as UploadFile;
const getPossibleExt = (contentType: string, contentDisposition: string, url: string): string =>{
const contentDispositionFileNameMatches = contentDisposition.match(/filename="(.*)"/);
const contentDispositionFileName = contentDispositionFileNameMatches ? contentDispositionFileNameMatches[1] : '';
const contentDispositionExt = contentDispositionFileName ? contentDispositionFileName.split('.').pop() : '';
if (contentDispositionExt) {
return contentDispositionExt;
}
const urlPath = harmonyUrl1.URL.parseURL(url).pathname;
const urlExt = urlPath.split('/').pop()?.split('.')[1] || '';
if (urlExt) {
return urlExt;
}
const contentTypeExt = lookupExt(contentType);
return contentTypeExt || '';
};
class DownloadTask1 implements DownloadTask {
__v_skip: boolean = true;
private _downloadTask: IDownloadTask;
constructor(downloadTask: IDownloadTask){
this._downloadTask = downloadTask;
}
abort() {
this._downloadTask.abort();
}
onProgressUpdate(callback: Function) {
this._downloadTask.onProgressUpdate(callback);
}
offProgressUpdate(callback: Function | null = null) {
this._downloadTask.offProgressUpdate(callback);
}
onHeadersReceived(callback: Function) {
this._downloadTask.onHeadersReceived(callback);
}
offHeadersReceived(callback: Function | null = null) {
this._downloadTask.offHeadersReceived(callback);
}
}
let downloadIndex: [string, number] = [
'0',
0
];
const getDownloadFileName = (ext: string)=>{
let fileName = Date.now() + '';
if (downloadIndex[0] === fileName) {
downloadIndex[1]++;
if (downloadIndex[1] > 0) {
fileName += '-' + downloadIndex[1];
}
} else {
downloadIndex[0] = fileName;
downloadIndex[1] = 0;
}
if (ext) {
fileName += '.' + ext;
}
return fileName;
};
const downloadFile = defineTaskApi<DownloadFileOptions, DownloadFileSuccess, DownloadTask>(API_DOWNLOAD_FILE, (args: DownloadFileOptions, exec: ApiExecutor<DownloadFileSuccess>)=>{
let url = args.url, timeout = args.timeout, header = args.header, filePath = args.filePath;
header = header || {} as ESObject;
if (!header!['Cookie'] && !header!['cookie']) {
header!['Cookie'] = getCookieSync(url);
}
const httpRequest = http3.createHttp();
const mp = getCurrentMP3();
const userAgent = mp.userAgent.fullUserAgent;
if (userAgent && !header!['User-Agent'] && !header!['user-agent']) {
header!['User-Agent'] = userAgent;
}
const emitter = new Emitter4() as IUniDownloadFileEmitter;
const downloadTask: IDownloadTask = {
abort () {
emitter.off('headersReceive');
emitter.off('progress');
httpRequest.destroy();
},
onHeadersReceived (callback: Function) {
emitter.on('headersReceive', callback);
},
offHeadersReceived (callback: Function | null = null) {
emitter.off('headersReceive', callback);
},
onProgressUpdate (callback: Function) {
emitter.on('progress', callback);
},
offProgressUpdate (callback: Function | null = null) {
emitter.off('progress', callback);
}
};
const destroy = ()=>{
downloadTask.abort();
};
mp.on('beforeClose', destroy);
let responseContentType = '';
let responseContentDisposition = '';
let lastUrl = url;
httpRequest.on('headersReceive', (headers: Object)=>{
const realHeaders = headers as Record<string, string | string[]>;
responseContentType = realHeaders['content-type'] as string || realHeaders['Content-Type'] as string || '';
responseContentDisposition = realHeaders['content-disposition'] as string || realHeaders['Content-Disposition'] as string || '';
const setCookieHeader = realHeaders['set-cookie'] || realHeaders['Set-Cookie'];
if (setCookieHeader) {
setCookieSync(lastUrl, setCookieHeader as string[]);
}
const location = realHeaders['location'] || realHeaders['Location'];
if (location) {
lastUrl = location as string;
}
});
httpRequest.on('dataReceiveProgress', (ref)=>{
let receiveSize = ref.receiveSize, totalSize = ref.totalSize;
emitter.emit('progress', {
progress: Math.floor((receiveSize / totalSize) * 100),
totalBytesWritten: receiveSize,
totalBytesExpectedToWrite: totalSize
} as OnProgressDownloadResult);
});
const TEMP_PATH = getEnv5().TEMP_PATH as string;
const downloadPath = TEMP_PATH + '/download';
if (!fs8.accessSync(downloadPath)) {
fs8.mkdirSync(downloadPath, true);
}
let stream: fs8.Stream;
let tempFilePath = '';
let writePromise = Promise.resolve(0);
const queueWrite = async (data: ArrayBuffer): Promise<number> =>{
writePromise = writePromise.then(async (total)=>{
const length = await stream.write(data);
return total + length;
});
return writePromise;
};
httpRequest.on('dataReceive', (data)=>{
if (!stream) {
const ext = getPossibleExt(responseContentType, responseContentDisposition, url);
tempFilePath = filePath ? filePath.replace(/^file:\/\//, '') : downloadPath + '/' + getDownloadFileName(ext);
stream = fs8.createStreamSync(tempFilePath, 'w+');
}
queueWrite(data);
});
httpRequest.requestInStream(parseUrl(url), {
header: header ? header : {} as ESObject,
method: http3.RequestMethod.GET,
connectTimeout: timeout ? timeout : undefined,
readTimeout: timeout ? timeout : undefined,
clientCert: getClientCertificate(url)
} as http3.HttpRequestOptions, (err, statusCode)=>{
let finishPromise: Promise<void> = Promise.resolve();
if (err) {
exec.reject(err.message);
} else {
finishPromise = writePromise.then(async ()=>{
await stream.flush();
await stream.close();
exec.resolve({
tempFilePath,
statusCode
} as DownloadFileSuccess);
}).catch((err: Error)=>{
exec.reject(err.message);
});
}
finishPromise.then(()=>{
downloadTask.offHeadersReceived();
downloadTask.offProgressUpdate();
httpRequest.destroy();
mp.off('beforeClose', destroy);
});
});
return new DownloadTask1(downloadTask);
}, DownloadFileApiProtocol, DownloadFileApiOptions) as DownloadFile;
const configMTLS: ConfigMTLS = defineAsyncApi<ConfigMTLSOptions, ConfigMTLSSuccess>(API_CONFIG_MTLS, (args: ConfigMTLSOptions, executor: ApiExecutor<ConfigMTLSSuccess>)=>{
try {
args.certificates.forEach((certificate)=>{
const certHosts = certificates.map((cert)=>cert.host);
const certHostIndex = certHosts.indexOf(certificate.host);
if (certHostIndex > -1) {
certificates.splice(certHostIndex, 1);
}
certificates.push(certificate);
});
executor.resolve();
} catch (error) {
executor.reject((error as BusinessError13).message);
}
}, ConfigMTLSApiProtocol, ConfigMTLSApiOptions) as ConfigMTLS;
const API_LOGIN = 'login';
const LoginApiProtocol = new Map<string, ProtocolOptions>([
[
'provider',
{
type: 'string'
}
],
[
'timeout',
{
type: 'number'
}
]
]);
const API_GET_USER_INFO = 'getUserInfo';
const GetUserInfoApiProtocol = new Map<string, ProtocolOptions>([
[
'provider',
{
type: 'string'
}
],
[
'timeout',
{
type: 'number'
}
]
]);
const SERVICE = 'oauth';
const PROVIDER = 'huawei';
const login: Login = defineAsyncApi<LoginOptions, LoginSuccess>(API_LOGIN, (args: LoginOptions, executor: ApiExecutor<LoginSuccess>)=>{
const provider = getUniProvider<UniOAuthProvider>(SERVICE, args.provider ?? PROVIDER);
if (!provider) {
executor.reject('Provider not found.');
return;
}
provider.login({
success (res) {
executor.resolve(res);
},
fail (err) {
executor.reject(err.errMsg);
}
} as LoginOptions);
}, LoginApiProtocol) as Login;
const getUserInfo: GetUserInfo = defineAsyncApi<GetUserInfoOptions, GetUserInfoSuccess>(API_GET_USER_INFO, (args: GetUserInfoOptions, executor: ApiExecutor<GetUserInfoSuccess>)=>{
const provider = getUniProvider<UniOAuthProvider>(SERVICE, args.provider ?? PROVIDER);
if (!provider) {
executor.reject('Provider not found.');
return;
}
provider.getUserInfo({
success (res) {
executor.resolve(res);
},
fail (err) {
executor.reject(err.errMsg);
}
} as GetUserInfoOptions);
}, GetUserInfoApiProtocol) as GetUserInfo;
const API_OPEN_APP_AUTHORIZE_SETTING = 'openAppAuthorizeSetting';
const openAppAuthorizeSetting: OpenAppAuthorizeSetting = defineAsyncApi<OpenAppAuthorizeSettingOptions, OpenAppAuthorizeSettingSuccess>(API_OPEN_APP_AUTHORIZE_SETTING, (options: OpenAppAuthorizeSettingOptions, exec: ApiExecutor<OpenAppAuthorizeSettingSuccess>)=>{
const want: Want = {
bundleName: 'com.huawei.hmos.settings',
abilityName: 'com.huawei.hmos.settings.MainAbility',
uri: 'application_info_entry',
parameters: {
pushParams: bundleManager2.getBundleInfoForSelfSync(bundleManager2.BundleFlag.GET_BUNDLE_INFO_DEFAULT).name
}
} as Want;
const context = UTSHarmony.getUIAbilityContext() as common1.UIAbilityContext;
context.startAbility(want).then(()=>{
exec.resolve({
errMsg: ''
} as OpenAppAuthorizeSettingSuccess);
}, (err: Error)=>{
exec.reject(err.message);
});
}) as OpenAppAuthorizeSetting;
const API_OPEN_DOCUMENT = 'openDocument';
const getContentType = (filePath: string, fileType: string | null = null): string | void =>{
const suffix = fileType || filePath.split('.').pop();
if (!suffix) {
return;
}
switch(suffix){
case 'doc':
case 'docx':
return 'application/msword';
case 'xls':
case 'xlsx':
return 'application/vnd.ms-excel';
case 'ppt':
case 'pptx':
return 'application/vnd.ms-powerpoint';
case 'pdf':
return 'application/pdf';
default:
return;
}
};
const openDocument: OpenDocument = defineAsyncApi<OpenDocumentOptions, OpenDocumentSuccess>(API_OPEN_DOCUMENT, (options: OpenDocumentOptions, exec: ApiExecutor<OpenDocumentSuccess>)=>{
const filePath = options.filePath;
const uri = fileUri1.getUriFromPath(filePath.replace(/^file:\/\//, ''));
const fileContentType = getContentType(filePath, options.fileType);
if (!fileContentType) {
exec.reject('file type not supported');
return;
}
const want: Want1 = {
flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_PERSISTABLE_URI_PERMISSION,
action: 'ohos.want.action.viewData',
uri: uri,
type: fileContentType as string
};
const abilityContext = UTSHarmony.getUIAbilityContext() as common2.UIAbilityContext;
abilityContext.startAbility(want).then(()=>{
exec.resolve({} as OpenDocumentSuccess);
}, (err: Error)=>{
exec.reject(err.message);
});
}) as OpenDocument;
const RequestPaymentUniErrors: Map<RequestPaymentErrorCode, string> = new Map([
[
700600,
'The payment result is unknown (it may have been successfully paid). Please check the payment status of the order in the merchant order list.'
],
[
701100,
'Order payment failure.'
],
[
701110,
'Repeat the request.'
],
[
700601,
'The user canceled midway.'
],
[
700602,
'Network connection error.'
],
[
700603,
'Payment result unknown (may have been successfully paid), please check the payment status of the order in the merchant order list.'
],
[
700607,
'Payment not completed.'
],
[
700608,
'Parameter error.'
],
[
700000,
'Other payment errors.'
],
[
700604,
'Wechat is not installed.'
],
[
700605,
'Failed to get provider.'
],
[
700800,
'URL Scheme is not configured.'
],
[
700801,
'Universal Link is not configured.'
]
]);
const API_REQUEST_PAYMENT = 'requestPayment';
const requestPayment: RequestPayment = defineAsyncApi<RequestPaymentOptions, RequestPaymentSuccess>(API_REQUEST_PAYMENT, (options: RequestPaymentOptions, exec: ApiExecutor<RequestPaymentSuccess>): void =>{
const provider = getUniProvider<UniPaymentProvider>('payment', options.provider);
if (!provider) {
exec.reject('Provider not found.');
return;
}
provider.requestPayment({
orderInfo: options.orderInfo,
success: (result: RequestPaymentSuccess)=>{
exec.resolve(result);
},
fail: (error: RequestPaymentFail)=>{
const errMsg = RequestPaymentUniErrors.get(error.errCode) ?? "";
exec.reject(errMsg, {
errCode: error.errCode
} as ApiError);
}
} as RequestPaymentOptions);
}) as RequestPayment;
const API_SHOW_TOAST = 'showToast';
const ShowToastProtocol = new Map<string, ProtocolOptions>([
[
'title',
{
type: 'string',
required: true
}
],
[
'duration',
{
type: 'number'
}
]
]);
const ShowToastApiOptions: ApiOptions<ShowToastOptions> = {
formatArgs: new Map<string, Function | string | number>([
[
"title",
""
],
[
"duration",
1500
]
])
};
const API_HIDE_TOAST = 'hideToast';
const PRIMARY_COLOR = '#007aff';
const API_SHOW_MODAL = 'showModal';
const ShowModalProtocol = new Map<string, ProtocolOptions>([
[
"title",
{
type: "string"
}
],
[
"content",
{
type: "string"
}
],
[
"showCancel",
{
type: "boolean"
}
],
[
"cancelText",
{
type: "string"
}
],
[
"cancelColor",
{
type: "string"
}
],
[
"confirmText",
{
type: "string"
}
],
[
"confirmColor",
{
type: "string"
}
]
]);
const ShowModalApiOptions: ApiOptions<ShowModalOptions> = {
formatArgs: new Map<string, Function | string | boolean>([
[
"title",
""
],
[
"content",
""
],
[
"placeholderText",
""
],
[
"showCancel",
true
],
[
"editable",
false
],
[
"cancelColor",
"#000000"
],
[
"confirmColor",
PRIMARY_COLOR
]
])
};
const API_SHOW_ACTION_SHEET = 'showActionSheet';
const ShowActionSheetProtocol = new Map<string, ProtocolOptions>([
[
"title",
{
type: "string"
}
],
[
"itemList",
{
type: "array",
required: true
}
],
[
"itemColor",
{
type: "string"
}
]
]);
const ShowActionSheetApiOptions: ApiOptions<ShowActionSheetOptions> = {
formatArgs: new Map<string, string>([
[
"itemColor",
"#000000"
]
])
};
const API_SHOW_LOADING = 'showLoading';
const ShowLoadingProtocol = new Map<string, ProtocolOptions>([
[
'title',
{
type: 'string'
}
],
[
'mask',
{
type: 'boolean'
}
]
]);
const ShowLoadingApiOptions: ApiOptions<ShowLoadingOptions> = {
formatArgs: new Map<string, Function | string | boolean>([
[
"title",
""
],
[
"mask",
false
]
])
};
const API_HIDE_LOADING = 'hideLoading';
const showToast: ShowToast = defineAsyncApi<ShowToastOptions, ShowToastSuccess>(API_SHOW_TOAST, (options: ShowToastOptions, res: ApiExecutor<ShowToastSuccess>)=>{
try {
const showToastOptions: promptAction4.ShowToastOptions = {
message: options.title,
duration: options.duration!,
alignment: Alignment.Center
};
if (options.position) {
switch(options.position){
case 'top':
showToastOptions.alignment = Alignment.Top;
break;
case 'bottom':
showToastOptions.alignment = Alignment.Bottom;
break;
}
}
const window = UTSHarmony.getCurrentWindow() as window.Window;
window.getUIContext().getPromptAction().showToast(showToastOptions);
res.resolve({} as ShowToastSuccess);
} catch (error) {
let message = (error as BusinessError14).message;
res.reject(message);
}
}, ShowToastProtocol, ShowToastApiOptions) as ShowToast;
const hideToast: HideToast = defineAsyncApi(API_HIDE_TOAST, (_, res: ApiExecutor<Object>)=>{}) as HideToast;
const showModal: ShowModal = defineAsyncApi<ShowModalOptions, ShowModalSuccess>(API_SHOW_MODAL, async (args: ShowModalOptions, res: ApiExecutor<ShowModalSuccess>)=>{
const modalRes = await new Promise<ShowModalSuccess>((resolve, reject)=>{
const confirmButton: AlertDialogButtonOptions = {
value: args.confirmText ?? '确定',
fontColor: args.confirmColor!,
action: ()=>{
resolve({
"confirm": true
} as ShowModalSuccess);
}
};
const cancelButton: AlertDialogButtonOptions = {
value: args.cancelText ?? '取消',
fontColor: args.cancelColor ?? '#000000',
action: ()=>{
resolve({
"cancel": true
} as ShowModalSuccess);
}
};
const buttons: Array<AlertDialogButtonOptions> = [];
if (args.showCancel) {
buttons.push(cancelButton);
}
buttons.push(confirmButton);
const window = UTSHarmony.getCurrentWindow() as window.Window;
window.getUIContext().showAlertDialog({
title: args.title ?? '',
message: args.content ?? '',
autoCancel: false,
alignment: DialogAlignment.Center,
buttons,
cancel: ()=>{
resolve({
'cancel': true
} as ShowModalSuccess);
}
} as AlertDialogParamWithOptions);
});
if (modalRes.confirm) {
modalRes.cancel = false;
}
if (modalRes.cancel) {
modalRes.confirm = false;
}
modalRes.content = null;
res.resolve(modalRes as ShowModalSuccess);
}, ShowModalProtocol, ShowModalApiOptions) as ShowModal;
const showActionSheet: ShowActionSheet = defineAsyncApi<ShowActionSheetOptions, ShowActionSheetSuccess>(API_SHOW_ACTION_SHEET, async (options: ShowActionSheetOptions, res: ApiExecutor<ShowActionSheetSuccess>)=>{
const actionItemList = options.itemList.filter(Boolean);
if (actionItemList.length === 0) {
return;
}
type ActionMenuButtons = [promptAction5.Button, promptAction5.Button?, promptAction5.Button?, promptAction5.Button?, promptAction5.Button?, promptAction5.Button?];
const actionMenuButtons: ActionMenuButtons = [
{
text: actionItemList[0],
color: options.itemColor!
}
];
actionItemList.slice(1).forEach((item)=>{
actionMenuButtons.push({
text: item,
color: options.itemColor!
} as promptAction5.Button);
});
const window = UTSHarmony.getCurrentWindow() as window.Window;
window.getUIContext().getPromptAction().showActionMenu({
title: options.title,
buttons: actionMenuButtons
} as promptAction5.ActionMenuOptions).then((showACtionSheetRes)=>{
res.resolve({
tapIndex: showACtionSheetRes.index
} as ShowActionSheetSuccess);
}).catch((e: Error)=>{
if (e.message === 'cancel') {
res.reject('cancel');
return;
}
res.reject(e.message);
});
}, ShowActionSheetProtocol, ShowActionSheetApiOptions) as ShowActionSheet;
const showLoading: ShowLoading = defineAsyncApi<ShowLoadingOptions, ShowLoadingSuccess>(API_SHOW_LOADING, async (options: ShowLoadingOptions, exec: ApiExecutor<ShowLoadingSuccess>)=>{
onNativePageReady2().then((nativePage: Object)=>{
getOSRuntime1().showLoading({
title: options.title || '',
mask: options.mask == null ? false : options.mask
} as IShowLoadingOptions, nativePage);
exec.resolve({} as ShowLoadingSuccess);
});
}, ShowLoadingProtocol, ShowLoadingApiOptions) as ShowLoading;
const hideLoading: HideLoading = defineAsyncApi<IHideLoadingOptions, IHideLoadingSuccess>(API_HIDE_LOADING, (options: IHideLoadingOptions, exec: ApiExecutor<IHideLoadingSuccess>)=>{
onNativePageReady2().then((nativePage: Object)=>{
getOSRuntime1().hideLoading();
exec.resolve({} as IHideLoadingSuccess);
});
}) as HideLoading;
const API_START_PULL_DOWN_REFRESH = 'startPullDownRefresh';
const API_STOP_PULL_DOWN_REFRESH = 'stopPullDownRefresh';
const startPullDownRefresh = defineAsyncApi<StartPullDownRefreshOptions, StartPullDownRefreshSuccess>(API_START_PULL_DOWN_REFRESH, (_, res)=>{
internalStartPullDownRefresh();
res.resolve();
}) as StartPullDownRefresh;
const stopPullDownRefresh = defineSyncApi<void>(API_STOP_PULL_DOWN_REFRESH, ()=>{
internalStopPullDownRefresh();
}) as StopPullDownRefresh;
const API_RPX2PX = 'rpx2px';
const EPS = 1e-4;
const rpx2px: Rpx2px = defineSyncApi<number>(API_RPX2PX, (number: number): number =>{
const windowStage: harmonyWindow.WindowStage = UTSHarmony.getWindowStage() as harmonyWindow.WindowStage;
let windowWidthInVp: number = 384;
let windowWidthInPx: number = 1344;
if (windowStage) {
const mainWindow: harmonyWindow.Window = windowStage.getMainWindowSync();
windowWidthInPx = mainWindow.getWindowProperties().windowRect.width;
windowWidthInVp = px2vp(windowWidthInPx);
}
let result = (number / 750) * windowWidthInVp;
if (result < 0) {
result = -result;
}
result = Math.floor(result + EPS);
if (result == 0) {
if (windowWidthInPx == windowWidthInVp) {
result = 1;
} else {
result = 0.5;
}
}
return number < 0 ? -result : result;
}) as Rpx2px;
const API_SCAN_CODE = 'scanCode';
const HarmonyScanTypeMap = new Map<UniScanOptionsTypes, scanCore.ScanType[]>([
[
'barCode',
[
scanCore.ScanType.ONE_D_CODE
]
],
[
'qrCode',
[
scanCore.ScanType.TWO_D_CODE
]
],
[
'datamatrix',
[
scanCore.ScanType.DATAMATRIX_CODE
]
],
[
'pdf417',
[
scanCore.ScanType.PDF417_CODE
]
]
]);
const UniScanTypeMap = new Map<HarmonyScanResultTypes, UniScanResultTypes>([
[
scanCore.ScanType.AZTEC_CODE,
'AZTEC'
],
[
scanCore.ScanType.CODABAR_CODE,
'CODABAR'
],
[
scanCore.ScanType.CODE128_CODE,
'CODE_128'
],
[
scanCore.ScanType.CODE39_CODE,
'CODE_39'
],
[
scanCore.ScanType.CODE93_CODE,
'CODE_93'
],
[
scanCore.ScanType.DATAMATRIX_CODE,
'DATA_MATRIX'
],
[
scanCore.ScanType.EAN13_CODE,
'EAN_13'
],
[
scanCore.ScanType.EAN8_CODE,
'EAN_8'
],
[
scanCore.ScanType.ITF14_CODE,
'ITF'
],
[
scanCore.ScanType.PDF417_CODE,
'PDF_417'
],
[
scanCore.ScanType.QR_CODE,
'QR_CODE'
],
[
scanCore.ScanType.UPC_A_CODE,
'UPC_A'
],
[
scanCore.ScanType.UPC_E_CODE,
'UPC_E'
]
]);
const scanCode: ScanCode = defineAsyncApi<ScanCodeOptions, ScanCodeSuccess>(API_SCAN_CODE, (options: ScanCodeOptions, exec: ApiExecutor<ScanCodeSuccess>)=>{
if (!canIUse('SystemCapability.Multimedia.Scan.ScanBarcode')) {
exec.reject('not support');
return;
}
let scanTypes: scanCore.ScanType[] = [];
if (options.scanType && Array.isArray(options.scanType) && options.scanType.length > 0) {
for(let i = 0; i < options.scanType.length; i++){
const uniScanType = options.scanType[i];
const harmonyScanTypes = HarmonyScanTypeMap.get(uniScanType);
if (!harmonyScanTypes) {
continue;
}
scanTypes = scanTypes.concat(harmonyScanTypes);
}
}
if (scanTypes.length === 0) {
scanTypes = [
scanCore.ScanType.ALL
];
}
const scanOptions: scanBarcode.ScanOptions = {
scanTypes,
enableMultiMode: true,
enableAlbum: !options.onlyFromCamera
};
scanBarcode.startScanForResult(UTSHarmony.getUIAbilityContext()!, scanOptions, (err, data)=>{
if (err) {
exec.reject(err.message);
return;
}
exec.resolve({
result: data.originalValue,
scanType: UniScanTypeMap.get(data.scanType as HarmonyScanResultTypes) || ''
} as ScanCodeSuccess);
});
}) as ScanCode;
const API_SHARE_WITH_SYSTEM = 'shareWithSystem';
const shareWithSystem = defineAsyncApi<ShareWithSystemOptions, ShareWithSystemSuccess>(API_SHARE_WITH_SYSTEM, (args: ShareWithSystemOptions, exec: ApiExecutor<ShareWithSystemSuccess>)=>{
const href = args.href;
const imageUrl = args.imageUrl;
const summary = args.summary;
const shareRecords: systemShare.SharedRecord[] = [];
if (href) {
shareRecords.push({
utd: uniformTypeDescriptor1.UniformDataType.HYPERLINK,
content: href
} as systemShare.SharedRecord);
}
if (imageUrl) {
shareRecords.push({
utd: uniformTypeDescriptor1.UniformDataType.IMAGE,
uri: imageUrl
} as systemShare.SharedRecord);
}
if (summary) {
shareRecords.push({
utd: uniformTypeDescriptor1.UniformDataType.TEXT,
content: summary
} as systemShare.SharedRecord);
}
if (shareRecords.length === 0) {
exec.reject('No share data');
return;
}
const shareData = new systemShare.SharedData(shareRecords[0]);
for(let index = 1; index < shareRecords.length; index++){
shareData.addRecord(shareRecords[index]);
}
const shareController: systemShare.ShareController = new systemShare.ShareController(shareData);
shareController.show(UTSHarmony.getUIAbilityContext() as common3.UIAbilityContext, {} as systemShare.ShareControllerOptions);
const onDismiss = ()=>{
shareController.off('dismiss', onDismiss);
exec.resolve({} as ShareWithSystemSuccess);
};
shareController.on('dismiss', onDismiss);
}) as ShareWithSystem;
const API_GET_STORAGE = 'getStorage';
const API_GET_STORAGE_SYNC = 'getStorageSync';
const API_SET_STORAGE = 'setStorage';
const API_SET_STORAGE_SYNC = 'setStorageSync';
const API_REMOVE_STORAGE = 'removeStorage';
const API_REMOVE_STORAGE_SYNC = 'removeStorageSync';
const API_CLEAR_STORAGE = 'clearStorage';
const API_CLEAR_STORAGE_SYNC = 'clearStorageSync';
const API_GET_STORAGE_INFO = 'getStorageInfo';
const API_GET_STORAGE_INFO_SYNC = 'getStorageInfoSync';
const parseStorageValue = (value: string): Object =>{
try {
return JSON.parse(value).data;
} catch (e) {
return value;
}
};
const stringifyStorageValue = (value: Object): string =>{
return JSON.stringify({
type: typeof value,
data: value
} as ESObject);
};
const stores = new Map<string, dataPreferences.Preferences>();
const createStore = (): dataPreferences.Preferences =>{
const id = getCurrentMP4().id;
if (stores.has(id)) {
return stores.get(id)!;
}
const store = dataPreferences.getPreferencesSync(UTSHarmony.getUIAbilityContext() as common4.UIAbilityContext, {
name: `storage.${id}`
} as dataPreferences.Options);
stores.set(id, store);
return store;
};
const getStorageSync = defineSyncApi<Object>(API_GET_STORAGE_SYNC, (key: string)=>{
const storeValue = createStore().getSync(key, '');
if (!storeValue) {
return '';
}
return parseStorageValue(storeValue as string);
}) as GetStorageSync;
const getStorage = defineAsyncApi<GetStorageOptions, GetStorageSuccess>(API_GET_STORAGE, (args: GetStorageOptions, exec: ApiExecutor<GetStorageSuccess>)=>{
createStore().get(args.key, '').then((storeValue)=>{
if (!storeValue) {
return exec.reject('data not found');
}
let value: Object;
try {
value = parseStorageValue(storeValue as string);
} catch (error) {
exec.reject('data parse error');
return;
}
exec.resolve({
data: value
} as GetStorageSuccess);
});
}) as GetStorage;
const setStorageSync = defineSyncApi<void>(API_SET_STORAGE_SYNC, (key: string, value: Object)=>{
createStore().putSync(key, stringifyStorageValue(value));
createStore().flush();
}) as SetStorageSync;
const setStorage = defineAsyncApi<SetStorageOptions, SetStorageSuccess>(API_SET_STORAGE, (args: SetStorageOptions, exec: ApiExecutor<SetStorageSuccess>)=>{
try {
createStore().put(args.key, stringifyStorageValue(args.data)).then(()=>{
createStore().flush();
exec.resolve({} as ESObject);
}, (error: Error)=>{
exec.reject(error.message);
});
} catch (error) {
exec.reject((error as Error).message);
}
}) as SetStorage;
const removeStorageSync = defineSyncApi<void>(API_REMOVE_STORAGE_SYNC, (key: string)=>{
createStore().deleteSync(key);
createStore().flush();
}) as RemoveStorageSync;
const removeStorage = defineAsyncApi<RemoveStorageOptions, RemoveStorageSuccess>(API_REMOVE_STORAGE, (args: RemoveStorageOptions, exec: ApiExecutor<RemoveStorageSuccess>)=>{
createStore().delete(args.key).then(()=>{
createStore().flush();
exec.resolve({} as ESObject);
}, (error: Error)=>{
exec.reject(error.message);
});
}) as RemoveStorage;
const clearStorageSync = defineSyncApi<void>(API_CLEAR_STORAGE_SYNC, ()=>{
createStore().clearSync();
createStore().flush();
}) as ClearStorageSync;
const clearStorage = defineAsyncApi<ClearStorageOptions, ClearStorageSuccess>(API_CLEAR_STORAGE, (args: ClearStorageOptions, exec: ApiExecutor<ClearStorageSuccess>)=>{
createStore().clear().then(()=>{
createStore().flush();
exec.resolve({} as ESObject);
}, (error: Error)=>{
exec.reject(error.message);
});
}) as ClearStorage;
const getStorageInfoSync = defineSyncApi<GetStorageInfoSuccess>(API_GET_STORAGE_INFO_SYNC, ()=>{
const allData = createStore().getAllSync();
return {
keys: Object.keys(allData),
currentSize: 0,
limitSize: 0
} as GetStorageInfoSuccess;
}) as GetStorageInfoSync;
const getStorageInfo = defineAsyncApi<GetStorageInfoOptions, GetStorageInfoSuccess>(API_GET_STORAGE_INFO, (args: GetStorageInfoOptions, exec: ApiExecutor<GetStorageInfoSuccess>)=>{
createStore().getAll().then((allData)=>{
exec.resolve({
keys: Object.keys(allData),
currentSize: 0,
limitSize: 0
} as GetStorageInfoSuccess);
});
}) as GetStorageInfo;
const API_CONNECT_SOCKET = 'connectSocket';
const ConnectSocketApiProtocol = new Map<string, ProtocolOptions>([
[
'url',
{
type: 'string',
required: true
}
],
[
'header',
{
type: 'object',
required: false
}
],
[
'protocols',
{
type: 'string[]',
required: false
}
]
]);
const ConnectSocketApiOptions: ApiOptions<ConnectSocketOptions> = {
formatArgs: new Map<string, Function>([
[
'url',
(url: string, params: ConnectSocketOptions)=>{
if (url == null) {
throw new Error('url is required');
}
}
]
])
};
const API_SEND_SOCKET_MESSAGE = 'sendSocketMessage';
const API_CLOSE_SOCKET = 'closeSocket';
const tryExec = (fn: Function | null | undefined, ...args: Object[])=>{
if (!fn) {
return;
}
try {
fn(...args);
} catch (error) {
console.error(error);
}
};
const GlobalWebsocketEmitter = new Emitter5() as IUniWebsocketEmitter;
const destroySocketTaskEmitter = (emitter: IUniWebsocketEmitter)=>{
emitter.off('message');
emitter.off('open');
emitter.off('error');
emitter.off('close');
};
class SocketTask1 implements SocketTask {
__v_skip: boolean = true;
_destroy: Function;
private _ws: webSocket.WebSocket;
private _emitter: IUniWebsocketEmitter = new Emitter5() as IUniWebsocketEmitter;
constructor(ws: webSocket.WebSocket){
const mp = getCurrentMP5();
this._ws = ws;
this._ws.on('message', (_, data)=>{
const message = {
data
} as OnSocketMessageCallbackResult;
this._emitter.emit('message', message);
const socketTasks = getSocketTasks(mp.id);
if (this === socketTasks[0]) {
GlobalWebsocketEmitter.emit('message', message);
}
});
this._ws.on('open', (_, data)=>{
this._emitter.emit('open', data);
const socketTasks = getSocketTasks(mp.id);
if (this === socketTasks[0]) {
GlobalWebsocketEmitter.emit('open', data);
}
});
this._ws.on('error', (error)=>{
const message = {
errMsg: error.message
} as OnSocketErrorCallbackResult;
this._emitter.emit('error', message);
const socketTasks = getSocketTasks(mp.id);
if (this === socketTasks[0]) {
GlobalWebsocketEmitter.emit('error', message);
}
});
this._ws.on('close', (_, data)=>{
this._emitter.emit('close', data);
const socketTasks = getSocketTasks(mp.id);
if (this === socketTasks[0]) {
GlobalWebsocketEmitter.emit('close', data);
}
const index = socketTasks.indexOf(this);
if (index >= 0) {
socketTasks.splice(index, 1);
}
});
this._destroy = ()=>{
destroySocketTaskEmitter(this._emitter);
this.close();
};
}
send(options: SendSocketMessageOptions) {
this._ws.send(options.data as string | ArrayBuffer).then((success: boolean)=>{
if (success) {
tryExec(options.success, {} as GeneralCallbackResult);
} else {
tryExec(options.fail, new UniError('send message failed'));
}
}, (err: Error)=>{
tryExec(options.fail, new UniError(err.message));
});
}
close(options: CloseSocketOptions | null = null) {
this._ws.close({
code: typeof options?.code === 'number' ? options.code : 1000,
reason: typeof options?.reason === 'string' ? options.reason : ''
} as webSocket.WebSocketCloseOptions).then((success: boolean)=>{
if (success) {
tryExec(options?.success, {} as GeneralCallbackResult);
} else {
tryExec(options?.fail, new UniError('close socket failed'));
}
}, (err: Error)=>{
tryExec(options?.fail, new UniError(err.message));
});
}
onMessage(callback: Function) {
this._emitter.on('message', callback);
}
onOpen(callback: Function) {
this._emitter.on('open', callback);
}
onError(callback: Function) {
this._emitter.on('error', callback);
}
onClose(callback: Function) {
this._emitter.on('close', callback);
}
}
const socketTasksMap: Map<string, SocketTask1[]> = new Map();
const addSocketTask = (task: SocketTask1)=>{
const mp = getCurrentMP5();
mp.on('beforeClose', task._destroy);
task.onClose(()=>{
mp.off('beforeClose', task._destroy);
});
const id = mp.id;
if (!socketTasksMap.has(id)) {
socketTasksMap.set(id, []);
}
const socketTasks = socketTasksMap.get(id) as SocketTask1[];
socketTasks.push(task);
};
const getSocketTasks = (id: string | null = null)=>{
if (!id) {
const mp = getCurrentMP5();
id = mp.id;
}
return socketTasksMap.get(id!) || [];
};
const connectSocket = defineTaskApi<ConnectSocketOptions, ConnectSocketSuccess, SocketTask>(API_CONNECT_SOCKET, (args: ConnectSocketOptions, exec: ApiExecutor<ConnectSocketSuccess>)=>{
const ws = webSocket.createWebSocket();
const mp = getCurrentMP5();
ws.connect(args.url, {
header: args.header ? args.header as Object : undefined,
protocol: args.protocols ? Array.isArray(args.protocols) ? args.protocols.join(',') : args.protocols : ''
} as webSocket.WebSocketRequestOptions);
const task = new SocketTask1(ws);
mp.on('beforeClose', task._destroy);
task.onClose(()=>{
mp.off('beforeClose', task._destroy);
});
addSocketTask(task);
return task;
}, ConnectSocketApiProtocol, ConnectSocketApiOptions) as ConnectSocket;
const onSocketMessage: OnSocketMessage = (callback: Function)=>{
GlobalWebsocketEmitter.on('message', callback);
};
const onSocketOpen: OnSocketOpen = (callback: Function)=>{
GlobalWebsocketEmitter.on('open', callback);
};
const onSocketError: OnSocketError = (callback: Function)=>{
GlobalWebsocketEmitter.on('error', callback);
};
const onSocketClose: OnSocketClose = (callback: Function)=>{
GlobalWebsocketEmitter.on('close', callback);
};
const sendSocketMessage = defineAsyncApi<SendSocketMessageOptions, GeneralCallbackResult>(API_SEND_SOCKET_MESSAGE, (args: SendSocketMessageOptions, exec: ApiExecutor<GeneralCallbackResult>)=>{
const socketTasks = getSocketTasks();
const task = socketTasks[0];
if (task) {
task.send({
data: args.data,
success (res) {
exec.resolve(res);
},
fail (err) {
exec.reject('sendSocketMessage:fail');
}
} as SendSocketMessageOptions);
} else {
exec.reject('WebSocket is not connected');
}
}) as SendSocketMessage;
const closeSocket = defineAsyncApi<CloseSocketOptions, GeneralCallbackResult>(API_CLOSE_SOCKET, (args: CloseSocketOptions, exec: ApiExecutor<GeneralCallbackResult>)=>{
const socketTasks = getSocketTasks();
const task = socketTasks[0];
if (task) {
task.close({
code: args.code,
reason: args.reason,
success (res) {
exec.resolve(res);
},
fail (err) {
exec.reject('closeSocket:fail');
}
} as CloseSocketOptions);
} else {
exec.reject('WebSocket is not connected');
}
}) as CloseSocket;
return {
addPhoneContact,
startSoterAuthentication,
checkIsSupportSoterAuthentication,
checkIsSoterEnrolledInDevice,
chooseMedia,
getClipboardData,
setClipboardData,
createInnerAudioContext,
$on,
$once,
$off,
$emit,
exit,
saveFile,
getSavedFileList,
getSavedFileInfo,
removeSavedFile,
getFileInfo,
getFileSystemManager,
getAppAuthorizeSetting,
getAppBaseInfo,
getBackgroundAudioManager,
getDeviceInfo,
getNetworkType,
onNetworkStatusChange,
offNetworkStatusChange,
getProvider,
getProviderSync,
getRecorderManager,
getSystemInfo,
getSystemInfoSync,
getWindowInfo,
getSystemSetting,
hideKeyboard,
makePhoneCall,
chooseImage,
previewImage,
closePreviewImage,
getImageInfo,
saveImageToPhotosAlbum,
compressImage,
chooseVideo,
saveVideoToPhotosAlbum,
getVideoInfo,
compressVideo,
chooseFile,
request,
uploadFile,
downloadFile,
configMTLS,
login,
getUserInfo,
openAppAuthorizeSetting,
openDocument,
requestPayment,
showToast,
hideToast,
showLoading,
hideLoading,
showModal,
showActionSheet,
startPullDownRefresh,
stopPullDownRefresh,
rpx2px,
scanCode,
shareWithSystem,
setStorage,
setStorageSync,
getStorage,
getStorageSync,
getStorageInfo,
getStorageInfoSync,
removeStorage,
removeStorageSync,
clearStorage,
clearStorageSync,
connectSocket,
sendSocketMessage,
closeSocket,
onSocketOpen,
onSocketMessage,
onSocketClose,
onSocketError
} as UniExtApi;
}